未经检查的带有参数化类型的转换警告

问题描述:

我在阅读有关Java教程中对泛型的限制,特别是casting with parameterized types。我理解所提供的例子。不过,我不确定下面的例子:未经检查的带有参数化类型的转换警告

List<? extends Number> l1 = new ArrayList<Integer>(); 
// unchecked cast warning 
ArrayList<Number> l2 = (ArrayList<Number>) l1; 
// no unchecked cast warning 
ArrayList<? extends Number> l3 = (ArrayList<? extends Number>) l1; 

我明白为什么在第一种情况下会出现警告。为什么在第二种情况下没有警告?是否因为我可以在l3上执行的唯一操作是安全的(例如,我不能在列表中添加(说)Float)?


UPDATE:下面是从section 5.5.2 of the JLS,解决类似的问题的摘录。

从类型S的流延到一个参数化的类型(§4.5)T未选中 除非以下中的至少一项为真:

  • S <: T
  • 所有的类型参数( §4.5.1)T是*通配符
  • T <: SS没有T其中X的类型参数未包含在T的类型参数中。

没有警告,因为转换不会改变类型的泛型部分。 List<? extends Number>ArrayList<? extends Number>具有相同的类型参数。相反,演员阵容是从ListArrayList