addAll(Collection<? extends E> c)

addAll(Collection<? extends E> c)
K8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 13
0

Witam, dlaczego poniższy kod się kompiluje? W metodzie addAll(Collection<? extends E> c) z klasy Vector, składnia <? extends E> oznacza "some type that either is E or a subtype of E", a przecież klasa Stack dziedziczy z klasy Vector, więc Vector nie jest podtypem klasy Stack (tylko Stack jest podtypem klasy Vector).

Kopiuj
Stack<Integer> stack = new Stack<Integer>();

        stack.push(3);
        stack.push(5);
        stack.push(8);

        Vector v = new Vector();

        v.add(1);
        v.add(2);
        v.add("one");
        v.add("two");
        v.add(3);

       stack.addAll(v); 
LA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 112
0

W tym wypadku <? extends E> E to jest Integer. Natomiast jak widzimy ta metoda pochodzi z interfejsu Collection, a obie te klasy - Vector i Stack pochodzą od tego właśnie interfejsu.

E tutaj dotyczy typów elementów kolekcji, a nie typu kolekcji.

KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5618
1
lavoholic napisał(a):

W tym wypadku <? extends E> E to jest Integer. Natomiast jak widzimy ta metoda pochodzi z interfejsu Collection, a obie te klasy - Vector i Stack pochodzą od tego właśnie interfejsu.

E tutaj dotyczy typów elementów kolekcji, a nie typu kolekcji.

Miałem już na ten temat przygotowaną ładną odpowiedź, którą skasowałem (ale wklejam ją poniżej), gdy zorientowałem się że chyba OP pyta nie o to o co pyta :P
Zauważ że udało mu się przemycić kilka elementów będącymi Stringami. Strzelam że są to niedoskonałości biblioteki kolekcji z czasów braku generyków w Javie

Moja ładna odpowiedź nie na temat:

  1. Działa bo Vector implementuje Collection.
  2. typ generyczny E odnosi się do typu elementu a nie typu kolekcji. Czyli w tym wypadki do Integer
  3. Klas Stack i Vector nie powinno się używać bo są wolne (synchronizowane). Zamiast tego lepiej używać ArrayList
  4. W ogóle klas dziedziczących po Collection w Javie nie powinno się używać, bo są zepsute (zły dizajn interfejsu, z czasów mutowalnych kolekcji). A zamiast tego powinno się używać biblioteki vavr, ale to już kontrowersyjna opinia
K8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 13
0

Skoro E to Integer, to czym jest "?", bo musi to dziedziczyć po E lub być typem E, tak?

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
1

Samo Vector jest mniej więcej tożsame z Vector<Object> (w pewnych aspektach), natomiast kompilator i tak powinien się ciskać, gdy mieszasz kod generyczny z niegenerycznym. Coś w ten deseń wypluwa domyślnie:

Kopiuj
javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Jak dodasz tę opcję -Xlint:unchecked do wywołania javac to dostaniesz pełny opis błędu. Jeżeli nie jesteś pewien jakie masz problemy z generykami albo jak je naprawić to włączenie tej opcji jest w zasadzie wymagane.

LA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 112
1

W ogóle nie zauważyłem tych stringów @szweszwe, racja. To tutaj jeszcze jest ta kwestia, że nasz Vector w tym przypadku nie ma nadanego typu. Wtedy nie będzie żadnego problemu, ba Stack też go sobie bez problemowo przyjmie. Problem nastąpi gdy odpalimy sobie przykładowo stack.forEach(System.out::println), wykrzaczy nam się na próbie castowania String -> Integer.

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0
Karol8650 napisał(a):

Skoro E to Integer, to czym jest "?", bo musi to dziedziczyć po E lub być typem E, tak?

Jeśli E to Integer to w szczególnym przypadku ? extends E może oznaczać również Integera. Weź pod uwagę to, że extends w przypadku generyków oznacza górne ograniczenie (upper bound), natomiast extends w przypadku dziedziczenia wskazuje na klasę bazową (parent/ base/ etc class). Nie są to do końca tożsame pojęcia. Ponadto możesz zrobić ? super E w generykach, a nie zrobisz class CośTam super CośInnego więc to kolejny dowód na to, że te słowa kluczowe oznaczają nieco inną rzecz w różnych kontekstach.

szweszwe
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 1694
1
Wibowit napisał(a):

Samo Vector jest mniej więcej tożsame z Vector<Object>

Tylko ta pierwsza wersja się kompiluje a druga nie. No i padło pytanie 'dlaczego'. Jest jakiś konkretny powód?

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
1

OK. Teraz rozumiem. Myślałem, że pytanie było "dlaczego poniższy kod się NIE kompiluje", a jest przecież "dlaczego poniższy kod się kompiluje". Otóż kompiluje się, ale z ostrzeżeniami, więc trzeba samemu ocenić czy te ostrzeżenia wskazują na niebezpieczeństwo. Tutaj tak, bo do Stack<Integer> dodajesz Stringi, więc kod wybuchnie w runtime jak będziesz chciał wyciągnąć tego Stringa z kolekcji typu Stack<Integer>. Najlepiej po prostu napisać kod z poprawnymi generykami, taki który nie będzie generował ostrzeżeń i nie będzie naszpikowany ręcznymi rzutowaniami.

K8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 13
0

Już chyba wszystko rozumiem, dziękuję za pomoc.

szopn
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 11
0

Twoim problem jest tutaj to że używasz addAll w runtime, a typy genetyczne są usuwane podczas kompilacji i sa tam Objecty. Więc w runtime możesz wrzucić juz dowolny obiekt do Stack-a.

Jakbyś podał typ generyczny dla Vectora to kompilator wywaliłby ci kompilacje, a tak masz tylko ostrzeżenie bo nie można określić czy sie zgadzają typy czy nie.

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
1
szopn napisał(a):

Problem tutaj jest to że użycie addAll jest w runtime, a typy genetyczne są usuwane podczas kompilacji

Przed usuwaniem generyków kompilator sprawdza ich poprawność i rzuca ostrzeżeniami lub błędami jeśli coś się nie zgadza, więc trzeba się po prostu tym komunikatom przyjrzeć i rozwiązać zgłoszony przez kompilator problem.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.