生到<! - ? extends Object - >

时间:2010-08-22 23:12:32

标签: java generics

我只是不明白这一点。

List list = new ArrayList();
List <? extends Object> list1 = list; // unchecked conversion warning.

由于Object是Java中的最高上限,我看不出有任何理由说明警告存在。

更新1:

关于akf的回答:

我完全理解你在说什么。我已经知道了。 但是&lt; ? extends Object>是最高的上限。这意味着你有任何你想要的类型。基本上是<?> == <? extends Object>

您可以在代码上尝试此操作,然后您会看到<?> == <? extends Objects>

更新2:

关于Sheng's answer

List  list = new ArrayList ();
List.add("a");
List <? extends Runnable> list1 = list; //warning here

为什么没有警告?

List <?> list2 = list; // No warning here

更新3:

我只是重温上述内容并仍然感到困惑。

由于编译器允许以下内容:

  1. List a = new ArrayList();

  2. List <?> b = a;

  3. 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) {}
    
  4. 两者都是允许的。因此,在向<? extends Object>

    分配raw时,我仍然不明白为什么会出现未经检查的警告

5 个答案:

答案 0 :(得分:2)

This question,特别是this answer,详细了解?? extends Object之间的差异。我仍然没有找到任何说明为什么你会收到ListList<? extends Object>的警告。

答案 1 :(得分:1)

如果我正确思考,那么默认情况下,编译器会假设您的意思是

List<?> list = new ArrayList();

?意味着您可以拥有任何您想要的泛型类型。这就是为什么

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

有效,因为对于编译器来说它们是同一个东西

但是,当你这样做时

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

你限制了它的范围。因为您限制范围,所以会收到警告。是的,我知道你不认为你是,但对你的编译器。如果你完全确定你知道自己在做什么,那就忽略它或压制它

答案 2 :(得分:0)

假设我们在list1中使用Runnable而不是Object。编译正常,但运行时错误:

 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还是其他内容。

答案 3 :(得分:0)

我认为这是因为Java处理Bounded Wildcards的方式,因为List&lt;? extends Object&gt;不一样也不是List

的子类

最初这个概念对我来说有些困惑,我发现Generics in the Java Programming Language文档对于理解这些类型的泛型非常有用。

答案 4 :(得分:0)

我认为盛元路已经准确地解释了它。我想补充一点,每当你看到这样的事情时,请回顾以下两点:

  1. 您不能只将“任何类型”的容器转换为“有界类型”的容器(无论前者是否绑定到对象类型)。
  2. 每当你这样做时,你就会产生“堆污染”(请参阅​​Angelika Langer的Java Generics常见问题解答)以获取描述。