Chcę spróbować rozbić odpowiedź z @DerMike, aby wyjaśnić:
Po pierwsze, wymazywanie typów nie oznacza, że JDK eliminuje informacje o typach w czasie wykonywania. Jest to metoda umożliwiająca sprawdzanie typów w czasie kompilacji i zgodność typów w środowisku wykonawczym w tym samym języku. Jak sugeruje ten blok kodu, JDK zachowuje usunięte informacje o typie - po prostu nie jest powiązany z zaznaczonymi rzutami i innymi rzeczami.
Po drugie, zapewnia to informacje o typie ogólnym klasie ogólnej dokładnie o jeden poziom w górę w hierarchii od sprawdzanego typu konkretnego - tj. Abstrakcyjna klasa nadrzędna z parametrami typu ogólnego może znaleźć konkretne typy odpowiadające jej parametrom typu w celu konkretnej implementacji samej siebie która bezpośrednio po niej dziedziczy. Gdyby ta klasa nie była abstrakcyjna i została utworzona, lub konkretna implementacja byłaby o dwa poziomy niższa, to nie zadziałałoby (chociaż odrobina jimmyingu mogłaby sprawić, że miałaby zastosowanie do dowolnej z góry określonej liczby poziomów powyżej jednego lub do najniższej klasy z X parametrami typu ogólnego i tak dalej).
W każdym razie do wyjaśnienia. Oto kod ponownie, podzielony na linie dla ułatwienia wyszukiwania:
1 # Klasa genericParameter0OfThisClass =
2 # (klasa)
3 # ((ParameterizedType)
4 # getClass ()
5 # .getGenericSuperclass ())
6 # .getActualTypeArguments () [0];
Niech „my” będzie klasą abstrakcyjną z typami generycznymi zawierającymi ten kod. Czytając to z grubsza na lewą stronę:
- Linia 4 pobiera bieżącą instancję klasy konkretnej klasy. To identyfikuje konkretny typ naszego bezpośredniego potomka.
- Linia 5 otrzymuje nadtyp tej klasy jako typ; to my. Ponieważ jesteśmy typem parametrycznym, możemy bezpiecznie rzutować się na ParameterizedType (wiersz 3). Kluczem jest to, że kiedy Java określa ten obiekt Type, używa informacji o typie obecnych w elemencie potomnym do skojarzenia informacji o typie z naszymi parametrami typu w nowej instancji ParameterizedType. Teraz możemy uzyskać dostęp do konkretnych typów naszych leków generycznych.
- Linia 6 pobiera tablicę typów odwzorowanych na nasze typy generyczne, w kolejności zadeklarowanej w kodzie klasy. W tym przykładzie wyciągamy pierwszy parametr. To wraca jako typ.
- Linia 2 rzuca ostateczny typ zwrócony do klasy. Jest to bezpieczne, ponieważ wiemy, jakie typy są w stanie przyjmować nasze parametry typu ogólnego i możemy potwierdzić, że wszystkie będą klasami (nie jestem pewien, jak w Javie można by uzyskać ogólny parametr, który nie ma instancji klasy z tym związane).
... i to wszystko. Więc wypychamy informacje o typie z naszej własnej konkretnej implementacji z powrotem do siebie i używamy ich, aby uzyskać dostęp do uchwytu klasy. moglibyśmy podwoić getGenericSuperclass () i przejść o dwa poziomy lub wyeliminować getGenericSuperclass () i uzyskać wartości dla siebie jako konkretny typ (zastrzeżenie: nie testowałem tych scenariuszy, jeszcze nie pojawiły się dla mnie).
To staje się trudne, jeśli twoje konkretne dzieci są oddalone o dowolną liczbę przeskoków lub jeśli jesteś konkretny i nie ostateczny, a szczególnie trudny, jeśli oczekujesz, że którekolwiek z twoich (zmiennie głębokich) dzieci będzie miało własne rodzaje. Ale zwykle możesz projektować pod kątem tych rozważań, więc to daje Ci większość możliwości.
Mam nadzieję, że to komuś pomogło! Uznaję, że ten post jest starożytny. Prawdopodobnie wytnę to wyjaśnienie i zatrzymam na inne pytania.