Предупреждения компилятора при объявлении универсальных типов - PullRequest
4 голосов
/ 02 января 2012

Почему компилятор выдает предупреждение при объявлении переменной как

 List<? extends Object> list = new LinkedList();

Предупреждение:

Note: ZiggyTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Но он не выдает предупреждение, когда я объявляю переменную как

List<?> list = new LinkedList();

Ответы [ 2 ]

2 голосов
/ 02 января 2012

Это происходит в Java 5 и более поздних версиях, если вы используете коллекции без спецификаторов типов (например, Arraylist() вместо ArrayList<String>()). Это означает, что компилятор не может проверить, что вы используете коллекцию безопасным для типов способом, используя generics .

Чтобы избавиться от предупреждения, просто уточните, какой тип объектов вы храните в коллекции. Итак, вместо

List list = new ArrayList();

должно быть как

List<String> list = new ArrayList<String>();

В вашем случае, если вы измените это утверждение следующим образом,

List<? extends Object> list = new LinkedList<Object>();

он будет компилироваться без предупреждения, потому что теперь мы делаем его безопасным с помощью универсального типа (<Object>).

1 голос
/ 02 января 2012

Я не могу объяснить, почему компилятор не будет рассматривать их как эквивалентные, но, учитывая, что это не так, я попытаюсь объяснить, почему он отказывается это делать.

Первый (List<? extends Object>) утверждает, что тип объектов, содержащихся в List, имеет некоторый неизвестный тип, полученный из Object. Второй (List<?>) говорит меньше; это просто говорит о том, что тип объектов в списке неизвестен. В качестве верхней границы неизвестного типа не упоминается ни один ожидаемый супертип.

Чтобы проверить первое предположение, компилятор хочет услышать, как вы что-то говорите об ожидаемых типах, хранящихся в экземпляре List, сконструированном здесь как необработанный тип LinkedList, который ничего не говорит по этому вопросу. Однако, если вы должны построить экземпляр как тип LinkedList<Object>, вы по крайней мере гарантируете, что ковариант , считывающий против экземпляра, будет соответствовать вашему утверждению, а именно: некоторые вещи в этом списке вид Object.

Теперь, это все кажется глупым, потому что каждый ссылочный / не примитивный тип в Java расширяется Object, поэтому не должно быть никакой разницы в интерпретации между List<? extends Object> и List<?>; в конце концов, второй подразумевает первый в силу обязательной иерархии классов в системе типов языка.

...