Я читаю SCJP Моголов (3-е издание) (лучшая книга SCJP, с которой я сталкивался), и на странице 727 написано следующее:

class MyIntList extends ArrayList <Integer> {} // A reifiable subclass  

Теперь я просто немного озадачен. Я знаю, что подкласс имеет неуниверсальный тип, но поскольку он расширяет ArrayList , а параметризованный в конечном итоге будет удален, и этот подкласс унаследует свойства своего суперкласса, почему этот подкласс MyIntList будет реифицируемым типом ?

3
yapkm01 29 Авг 2011 в 21:33

3 ответа

Лучший ответ

Поскольку каждый экземпляр MyIntList является Array<Integer>, вы можете узнать нижнюю / верхнюю границы с помощью отражения.

Если вы сказали class MyNumberList<T extends Number> extends ArrayList<T> { ... }, вы все равно можете найти границы, но не совсем то, какими были T для конкретного экземпляра MyNumberList.

3
Dilum Ranatunga 29 Авг 2011 в 17:38

Из спецификации языка Java http://java.sun.com/docs/books/jls /third_edition/html/typesValues.html

4.7 Реифицируемые типы

Поскольку некоторая информация о типах стирается во время компиляции, не все типы доступны во время выполнения. Типы, которые полностью доступны во время выполнения, называются реифицируемыми типами. Тип является реифицируемым тогда и только тогда, когда выполняется одно из следующих условий:

  • Это относится к объявлению неуниверсального типа.
  • Это параметризованный тип, в котором все аргументы типа являются неограниченными подстановочными знаками (§4.5.1).
  • Это необработанный тип (§4.8).
  • Это примитивный тип (§4.2).
  • Это тип массива (§10.1), компонентный тип которого реализуем.
3
bpgergo 29 Авг 2011 в 17:39

Универсальный тип стирается во время компиляции ArrayList, но не во время компиляции MyIntList. Таким образом, во время выполнения вы можете узнать, что MyIntList расширяет ArrayList, вызывая MyIntList.class.getGenericSuperclass() и анализируя возвращенный объект.

Причина, по которой это возможно, заключается в том, что MyIntList сам по себе не является универсальным, а расширяет конкретный экземпляр ArrayList. Таким образом, эту информацию можно просто сохранить в объекте Class MyIntList (откуда она доступна с помощью метода, упомянутого выше).

0
Philipp Wendler 29 Авг 2011 в 17:48