Подтвердить что ты не робот

Сырье к <? 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 &lt;?&gt; cannot be 
    
    // written in the for (:) loop as shown here
    for (Object obj : c) {}
    

Оба допустимы. Поэтому я до сих пор не понимаю, почему неконтролируемое предупреждение при настройке raw на <? extends Object>

4b9b3361

Ответ 1

Этот вопрос, и в частности этот ответ, содержат более подробную информацию о различиях между ? и ? extends Object. Я все еще не нашел ничего, что говорит о том, почему вы получаете предупреждение с List до List<? extends Object>.

Ответ 2

Если я правильно думаю, то по умолчанию компилятор предполагает, что вы имеете в виду это

List<?> list = new ArrayList();

Что? означает, что вы можете иметь любой общий тип, который вы хотите. Вот почему

List list = new ArrayList();
List <?> list2 = list

работает, потому что для компилятора они одно и то же

Однако, когда вы делаете это

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

Вы ограничиваете свой охват. Поскольку вы ограничиваете область действия, вы получаете предупреждение. Да, я знаю, что ты не думаешь, что это так, но к компилятору. Если вы абсолютно уверены, что знаете, что делаете, просто игнорируйте его или подавляйте его.

Ответ 3

Предположим, если мы используем 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 или что-то еще.

Ответ 4

Я считаю, что это происходит из-за того, как Java обрабатывает ограниченные подстановочные знаки в этом списке <? расширяет Object > не является одним и тем же подклассом List

Первоначально понятие несколько сбивало с толку и меня, и я нашел Generics in the Java Programming Language, чрезвычайно полезный для понимания конкретно этих видов дженериков.

Ответ 5

Я думаю, что Shengyuanl Lu уже объяснил это точно. Я бы добавил, что всякий раз, когда вы видите такое, просто вспомните следующие два момента:

  • Вы не можете просто лить контейнер "любого типа" в контейнер "ограниченного типа" (независимо от того, имеет ли первый объект тип объекта).
  • Всякий раз, когда вы это делаете, вы создаете "загрязнение кучи" (см. часто задаваемые вопросы о генераторах Java-анимации Angelika Langer).