Ответ 1
Этот вопрос, и в частности этот ответ, содержат более подробную информацию о различиях между ?
и ? extends Object
. Я все еще не нашел ничего, что говорит о том, почему вы получаете предупреждение с List
до List<? extends Object>
.
Я просто этого не понимаю.
List list = new ArrayList();
List <? extends Object> list1 = list; // unchecked conversion warning.
Так как Object
- это верхняя верхняя граница Java, я не вижу причин, по которым это предупреждение.
Обновление 1:
Что касается ответа akf:
Я прекрасно понимаю, что вы говорите. Я уже знаю, что.
Но < ? extends Object>
- верхняя верхняя граница. Это означает, что у вас есть любой тип, который вы хотите. В основном <?> == <? extends Object>
.
Вы можете попробовать это на своем коде, и вы увидите <?> == <? extends Objects>
Обновление 2:
Что касается ответа Sheng:
List list = new ArrayList ();
List.add("a");
List <? extends Runnable> list1 = list; //warning here
Почему здесь нет предупреждений?
List <?> list2 = list; // No warning here
Обновление 3:
Я просто пересматриваю вышеупомянутое и все еще озадачен.
Так как компилятор допускает следующее:
List a = new ArrayList();
List <?> b = a;
List <? extends Object> c = a; // with warning of course
for (Object obj : b) {}
// I don't agree with your statements above that <?> cannot be
// written in the for (:) loop as shown here
for (Object obj : c) {}
Оба допустимы. Поэтому я до сих пор не понимаю, почему неконтролируемое предупреждение при настройке raw на <? extends Object>
Этот вопрос, и в частности этот ответ, содержат более подробную информацию о различиях между ?
и ? extends Object
. Я все еще не нашел ничего, что говорит о том, почему вы получаете предупреждение с List
до List<? extends Object>
.
Если я правильно думаю, то по умолчанию компилятор предполагает, что вы имеете в виду это
List<?> list = new ArrayList();
Что? означает, что вы можете иметь любой общий тип, который вы хотите. Вот почему
List list = new ArrayList();
List <?> list2 = list
работает, потому что для компилятора они одно и то же
Однако, когда вы делаете это
List<?> list = new ArrayList();
List<? extends Object> list2 = list
Вы ограничиваете свой охват. Поскольку вы ограничиваете область действия, вы получаете предупреждение. Да, я знаю, что ты не думаешь, что это так, но к компилятору. Если вы абсолютно уверены, что знаете, что делаете, просто игнорируйте его или подавляйте его.
Предположим, если мы используем Runnable
вместо Object
в списке1. Он компилируется нормально, но ошибка времени выполнения:
List list = new ArrayList ();
list.add("a");
List <? extends Runnable> list1 = list;
for(Runnable o:list1){ //Runtime exception-> java.lang.ClassCastException
o.run();
}
Случай показывает потенциальную проблему, вот почему предупреждение здесь.
Но ваша среда IDE просто проверяет синтаксис List <? extends SomeType>
, независимо от того, какой SomeType является Object
или что-то еще.
Я считаю, что это происходит из-за того, как Java обрабатывает ограниченные подстановочные знаки в этом списке <? расширяет Object > не является одним и тем же подклассом List
Первоначально понятие несколько сбивало с толку и меня, и я нашел Generics in the Java Programming Language, чрезвычайно полезный для понимания конкретно этих видов дженериков.
Я думаю, что Shengyuanl Lu уже объяснил это точно. Я бы добавил, что всякий раз, когда вы видите такое, просто вспомните следующие два момента: