为什么编译器问题的变量声明为编译器警告
时警告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();
为什么编译器问题的变量声明为编译器警告
时警告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();
我无法解释为什么编译器不会将这些视为等价的,但假定它不这样做,我会试着解释它为什么拒绝这么做。
第一个(List<? extends Object>
)声称List
中保存的对象的类型是来自Object
的某种未知类型。第二个(List<?>
)说少;它只是说列表中的对象的类型是未知的。它没有提及任何预期的超类型作为未知类型的上界。
为了验证第一个假设,编译器希望听到您说出在此处构造的List
实例中保留的预期类型,作为原始类型LinkedList
,该主题没有提到任何内容。但是,如果要将实例构造为LinkedList<Object>
类型,则至少要保证对实例的协变读取与您的断言保持一致:即,此列表中的内容是某种Object
。
现在,这一切似乎都傻了,因为Java中的每个参考/非原始类型扩展Object
,所以不应该在List<? extends Object>
和List<?>
之间的理解上发生歧义;毕竟,第二个意味着第一个意义上的,因为语言的类型系统的授权单根分类阶层。
这出现在Java 5和更高版本,如果您使用的集合没有类型说明符(例如Arraylist()
而不是ArrayList<String>()
)。这意味着编译器无法使用generics以类型安全的方式检查您是否正在使用该集合。
要摆脱警告,只需具体说明要在集合中存储什么类型的对象。所以,与其
List list = new ArrayList();
应尽可能
List<String> list = new ArrayList<String>();
在你的情况,如果你修改声明如下,
List<? extends Object> list = new LinkedList<Object>();
将与任何警告,因为编译我们现在使用通用类型(<Object>
)来使其类型安全。
结帐http://stackoverflow.com/questions/8683137/and-extends-object/8683314和我的答案中的优秀泛型教程那里是一个必须阅读时使用泛型 – Robin 2012-01-01 21:48:01
它不发布任何减少正如你在NetBeans 6.9.1中用jdk 6所提到的那样。 – Lion 2012-01-01 22:01:47
我没有使用IDE。从命令行提示编译时,是否会收到警告? – ziggy 2012-01-01 22:15:33