Автор оригинала: Sampada Wagde.
1. Обзор
В этом быстром учебнике мы увидим сходства и различия между > и расширяет объект> в Java Дженерики .
Тем не менее, это является продвинутой темой, крайне важно, чтобы получить базовое понимание этого вопроса, прежде чем погрузиться в суть вопроса.
2. Справочная информация о дженериках
Дженерики были введены в JDK 5 для устранения ошибок в компиляции времени и укрепления безопасности типа. Эта дополнительная безопасность типа устраняет литье в некоторых случаях использования и дает программистам возможность писать общие алгоритмы, оба из которых могут привести к более читаемому коду.
Например, предварительно JDK 5, мы должны работать с элементами списка с помощью литья. Это, в свою очередь, создало определенный класс ошибок времени выполнения:
List aList = new ArrayList(); aList.add(new Integer(1)); aList.add("a_string"); for (int i = 0; i < aList.size(); i++) { Integer x = (Integer) aList.get(i); }
Теперь в этом коде есть две проблемы, которые мы хотели бы решить:
- Нам нужен явный актерский состав, чтобы извлечь ценности из aList – тип зависит от переменного типа слева – Интегер в этом случае
- Мы получим ошибку времени выполнения на второй итерации, когда мы пытаемся бросить a_string к целое число
Дженерики заполняют роль для нас:
ListiList = new ArrayList<>(); iList.add(1); iList.add("a_string"); // compile time error for (int i = 0; i < iList.size(); i++) { int x = iList.get(i); }
Компилятор скажет нам, что это не возможно, чтобы добавить a_string к Список типа Интегер , что лучше, чем узнать во время выполнения.
Более того, явного литья не требуется, так как компилятор уже знает, что iList держит Интегер секунда. Кроме того, из-за магии распаковки, мы даже не нуждаются в Интегер типа, его примитивной формы достаточно.
3. Подстановочные знаки в дженериках
Вопросительный знак, или подстановочный знак, используется в дженериках для представления неизвестного типа. Он может иметь три формы:
- Неограниченные подстановочные : Список > представляет собой список неизвестного типа
- Верхние связанные wildcards : Список расширяет номер> представляет собой список Номер или его подтипы, такие как Интегер и двойной
- Нижние связанные wildcards : Список супер Integer> представляет собой список Интегер или его супер-типов Номер и объект
Теперь, с Объект является неотъемлемым супер-тип всех типов в Java, мы хотели бы поддаться искушению думать, что он также может представлять собой неизвестный тип. Другими словами, Список > и Список может служить той же цели. Но они этого не делают.
Рассмотрим эти два метода:
public static void printListObject(List
Учитывая список Интегер s, скажем:
Listli = Arrays.asList(1, 2, 3);
распечататьListObject (li) не будет компиляции, и мы получим эту ошибку:
The method printListObject(List
В то время как РаспечататьListWildCard (li) будет компилировать и будет 1 2 3
4. > и расширяет объект> – Сходства
В приведеном выше примере, если мы изменим подпись метода для РаспечататьЛистВилдКар Кому:
public static void printListWildCard(List extends Object> list)
Он будет функционировать так же, как распечататьListWildCard (список > список) сделал. Это связано с тем, что Объект является супертипом всех java-объектов, и в основном все Объект . Итак, Список Интегер s обрабатывается также.
Короче говоря, это означает, что ? и ? расширяет объект являются синонимами в этом примере .
Хотя в большинстве случаев это будет справедливо, но есть несколько отличий, а также . Давайте посмотрим на них в следующем разделе.
5. > и расширяет объект> – Разница
Поддающиеся проверке типы являются те, чей тип не стирается во время компиляции. Другими словами, не поддающийся проверке представление типа будет иметь меньше информации, чем его коллега по компиляции, потому что некоторые из них будут стерты.
Как правило, параметризированные типы не поддаются переопроблему. Это означает Список
Единственным исключением из этого правила являются неограниченные типы подстановочных карт. Это означает Список > и Карта,?> поддаются .
С другой стороны, Список расширяет объект> не поддающийся . Хотя тонкие, это заметное различие.
Не поддающиеся проверке типы не могут быть использованы в определенные ситуации например, в instanceof оператора или в качестве элементов массива.
Итак, если мы напишем:
List someList = new ArrayList<>(); boolean instanceTest = someList instanceof List>
Этот код компилирует и instanceTest это истинное .
Но, если мы используем instanceof оператор на Список расширяет объект> :
List anotherList = new ArrayList<>(); boolean instanceTest = anotherList instanceof List extends Object>;
затем строка 2 не компилирует.
Аналогичным образом, в приведенной ниже фрагменте строка 1 компилирует, но строка 2 не:
List>[] arrayOfList = new List>[1]; List extends Object>[] arrayOfAnotherList = new List extends Object>[1]
6. Заключение
В этом коротком учебнике мы увидели сходство и различия в > и расширяет объект> .
Хотя в основном похожи, Есть тонкие различия между ними с точки зрения их поддаются проверке или нет.