为什么在将变量声明为时编译器会发出警告
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();
如果您使用没有类型说明符的集合(例如,Arraylist()
而不是ArrayList<String>()
),这会出现在 Java 5 及更高版本中。这意味着编译器无法检查您是否使用泛型以类型安全的方式使用集合。
要消除警告,只需具体说明您在集合中存储的对象类型。所以,而不是
List list = new ArrayList();
应该是
List<String> list = new ArrayList<String>();
在您的情况下,如果您按如下方式修改该语句,
List<? extends Object> list = new LinkedList<Object>();
它会在没有警告的情况下编译,因为我们现在使用泛型类型 ( ) 使其类型安全<Object>
。
我无法解释为什么编译器不会将它们视为等效,但鉴于它没有,我将尝试解释为什么它拒绝这样做。
第一个 ( List<? extends Object>
) 断言保存在 中的对象的List
类型是从Object
. 第二个 ( List<?>
) 少说;它只是说列表中对象的类型是未知的。它没有提到任何预期的超类型作为未知类型的上限。
为了验证第一个假设,编译器希望听到您对List
这里构造为原始类型的实例中保存的预期类型发表一些看法LinkedList
,这对主题没有任何说明。但是,如果您要将实例构造为 type LinkedList<Object>
,您至少要保证对实例的协变读取将与您的断言一致:即,此列表中的事物是某种Object
.
现在,这一切似乎都很愚蠢,因为 Java 中的每个引用/非原始类型都 extends ,所以和;Object
之间的解释不应该有任何区别;毕竟,第二个意味着第一个,这得益于语言的类型系统强制的单根类层次结构。List<? extends Object>
List<?>