Przypomniał mi się taki kruczek w Javie, że jeżeli zabraknie jakiegoś parametru typu jakoś w klasie (nie pamiętam czy tworzenie instancji jako surowy bez <> czy np. wywołanie jakiejś metody statycznej czy coś), to ogólnie "cała klasa" przechodzi/czy jest tworzona w "trybie surowym", co powoduje że parametr typu w innym miejscu (nie pamiętam gdzie, może w klasie wewnętrznej tej klasy?) też całkowicie traci znaczenie, co jest dość zaskakujące i prowadzi do niespodziewanego błędu.
Coś w rodzaju, że mamy Klasa a ona gdzieś tam w środku ma (nie pamiętam czy w metodzie czy klasie wewnętrznej, czy gdzie) inny parametr np. , to jeżeli stworzymy jej instancję bez określenia T (na surowo) to o dziwo też nie będzie można skorzystać z "tego czegoś" co miało - również będzie surowe.
Kojarzy ktoś na czym to dokładniej polegało? nie umiem teraz znaleźć przykładu ani artkułu żadnego, a przydałby mi się.
@Eoghan: @EssePL: Niestety ani jedno, ani drugie. Kluczowe tu jest to, że mamy dwa różne parametry typu np. T i E.
Nasza klasa jest np. Klasa a gdzieś tam w jej wnętrzu jest coś z . Teoretycznei mamy dwa zupełnie różne niepowiązane paramtry trypu, ale jednak tworząc klasę surowo, tracimy całkowicie "generyczność" dotyczącą , czyli tak jakby cała klasa przechodzi "w tryb surowy".
@Eoghan: @EssePL: Już mi się przypomniało - jednak nie były to dwa nieokreślone parametry typu a konkretny parametr typu.
Jak zrobimy np. MojaKlasa implements Collection {....
Napiszemy sobie ładnie funkcje implementowanie z kolekcji, iterator() zwracający Iterator itd., to potem możemy się nadziać bo jak utworzymy naszą klasę:
MojaKlasa x = new MojaKlasa();
(czyli na surowo), to x.iterator() nie zwróci nam Iterator tylko surowego iteratora. Czyli przepada zarówno nasze jak i
@Eoghan: Dla mnie średnio logiczne, bo skoro nie podaje to czemu JVM ma nie wiedzieć, że klasa i tak implemetuje Collection tylko nagle sobie przyjmuje, że po prostu surowy Collection. Jedna z rzeczy, która chyba najbardziej zaskoczyła mnie w Javie.
Przy wymazywaniu typu implementowany Collection ma podstawiany typ String w argumentach, więc MojaKlasa też > musi korzystać ze String lub podtypu Stringa co wynika z dziedziczenia
Nie jest tak jak mówisz, tutaj dziedziczenie nie ma nic do rzeczy i nic mi nie broni korzystać sobie z T do woli, wymazaniem "siebie" będzie MojaKlasa a wymazaniem rodzia będzie Collection. Dlatego spokojnie mogę stworzyć obiekt:
shiiit, ale mi namieszałeś w głowie tym przykładem, a jeszcze bardziej sam sobie namieszałem :)
Co do eclipse to bardziej o inną kwestię chodzi - powieloną metodę add() dla Object i typu parametru tak jakby przesłonięcie w tym momencie nie działało. Jak tak teraz na to spojrzałem to właśnie kwestia Bridge Method z linka, którego wkleiłem. Wszystko się składa w całość :d
to x.iterator() nie zwróci nam Iterator<String> tylko surowego iteratora.
@hbpitero: Po prostu tak działa wolny ryn... ee tzn. "type erasure" w Javie. W czasie kompilacji typy generyczne są "wymazywane" i dlatego x.iterator() zwróci Ci w runtime typ "raw", a nie generyczny.
Więc jeśli dobrze rozumiem problem, te linki powinny rozjaśnić to trochę bardziej:
@BeSmarter: Nie chodzi mi o erasure, ja mam na myśli przejście w "tryb raw" jeszcze przed kompilacją, a nie przez erasure. Oczywiście w każdym przypadku podczas runtime iterator będzie surowy, ale z genericsem z automatu zostanie dodane rzutowanie. To o czym mówiłem, to to, że gdy mam deklarację klasy:
Coś w rodzaju, że mamy Klasa a ona gdzieś tam w środku ma (nie pamiętam czy w metodzie czy klasie wewnętrznej, czy gdzie) inny parametr np. , to jeżeli stworzymy jej instancję bez określenia T (na surowo) to o dziwo też nie będzie można skorzystać z "tego czegoś" co miało - również będzie surowe.
Kojarzy ktoś na czym to dokładniej polegało? nie umiem teraz znaleźć przykładu ani artkułu żadnego, a przydałby mi się.
#programowanie #java
Nasza klasa jest np. Klasa a gdzieś tam w jej wnętrzu jest coś z . Teoretycznei mamy dwa zupełnie różne niepowiązane paramtry trypu, ale jednak tworząc klasę surowo, tracimy całkowicie "generyczność" dotyczącą , czyli tak jakby cała klasa przechodzi "w tryb surowy".
Jednak właśnie dokładnie nie pamiętam jak to
Jak zrobimy np. MojaKlasa implements Collection {....
Napiszemy sobie ładnie funkcje implementowanie z kolekcji, iterator() zwracający Iterator itd., to potem możemy się nadziać bo jak utworzymy naszą klasę:
MojaKlasa x = new MojaKlasa();
(czyli na surowo), to x.iterator() nie zwróci nam Iterator tylko surowego iteratora. Czyli przepada zarówno nasze jak i
Czyli przepada zarówno nasze <T> jak i wpisane na sztywno <String> - taki jakby "tryb raw" dla całej klasy.
i z drugiego komentarza
tylko nagle sobie przyjmuje, że po prostu surowy Collection
no właśnie nie. Typ klasy generycznej jest dziedziczony z rodzica, więc w Twoim przykładzie:
MojaKlasa implements Collection {
Przy wymazywaniu typu implementowany Collection ma podstawiany typ String w argumentach,
Przy wymazywaniu typu implementowany Collection ma podstawiany typ String w argumentach, więc MojaKlasa też > musi korzystać ze String lub podtypu Stringa co wynika z dziedziczenia
Nie jest tak jak mówisz, tutaj dziedziczenie nie ma nic do rzeczy i nic mi nie broni korzystać sobie z T do woli, wymazaniem "siebie" będzie MojaKlasa a wymazaniem rodzia będzie Collection. Dlatego spokojnie mogę stworzyć obiekt:
new MojaKlasa();
Wtedy
Komentarz usunięty przez autora
Co do eclipse to bardziej o inną kwestię chodzi - powieloną metodę add() dla Object i typu parametru tak jakby przesłonięcie w tym momencie nie działało. Jak tak teraz na to spojrzałem to właśnie kwestia Bridge Method z linka, którego wkleiłem. Wszystko się składa w całość :d
@hbpitero: Po prostu tak działa wolny ryn... ee tzn. "type erasure" w Javie. W czasie kompilacji typy generyczne są "wymazywane" i dlatego x.iterator() zwróci Ci w runtime typ "raw", a nie generyczny.
Więc jeśli dobrze rozumiem problem, te linki powinny rozjaśnić to trochę bardziej:
http://stackoverflow.com/questions/313584/what-is-the-concept-of-erasure-in-generics-in-java
http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens
+ http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
W razie czego pytaj.
class MojaKlasa extends Iterable { ....
i stworzą sobie dwa obiekty tej klasy:
MojaKlasa a = new MojaKlasa<>();
MojaKlasa b = new