在Java7中使用菱形运算符

在Java7中使用菱形运算符,java,generics,Java,Generics,在Java 7之前,以下语法用于创建ArrayList ArrayList<Integer> ints = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7)); arraylistints=新的ArrayList(Arrays.asList(1,2,3,4,5,6,7)); 但是由于Java 7,我们可以省略构造函数中的泛型类型,即 ArrayList<Integer> ints = new Array

在Java 7之前,以下语法用于创建ArrayList

ArrayList<Integer> ints = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7));
arraylistints=新的ArrayList(Arrays.asList(1,2,3,4,5,6,7));
但是由于Java 7,我们可以省略构造函数中的泛型类型,即

ArrayList<Integer> ints = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
arraylistints=新的ArrayList(Arrays.asList(1,2,3,4,5,6,7));
但是当我试着做一些事情时

ArrayList<Number> nums = new ArrayList<>(Arrays.asList(1,2,3,4,4,5.5,6.6,7.7));
arraylistnums=新的ArrayList(Arrays.asList(1,2,3,4,4,5.5,6.6,7.7));
我得到了一个错误,但当我在右边提到泛型类型时

ArrayList<Number> nums = new ArrayList<Number>(Arrays.asList(1,2,3,4,5.5,6.6,7.7));
arraylistnums=新的ArrayList(Arrays.asList(1,2,3,4,5.5,6.6,7.7));
代码工作得很好。这背后的原因可能是什么


提前感谢。

数组。asList
是一种通用方法,因此从技术上讲,可以通过以下方式调用它:

Arrays.<Number> asList(1, 2, 3);
数组。asList(1,2,3);
甚至在Java7之前,当已知左手边时,该语言就可以进行一些有限的推理来消除这种情况,如

final List<Number> nums = Arrays.asList(1, 2, 3);
final List nums=Arrays.asList(1,2,3);

看起来您遇到了一个边缘案例,这两种类型的推理无法成功组合,菱形推理和泛型方法推理无法相处。如果你仔细研究一下,我也肯定。Java泛型是不变的,而数组是协变的

如果Java中的泛型是协变的,如果
A
B
的子类型,那么
List[A]
List[B]
的子类型。但在Java中并非如此。(Scala有一个协方差实现。在Scala中,如果
B
扩展
a
,则
List[B]
扩展
List[a]

但是
String[]
Object[]


因此,
ArrayList
不能像您的情况那样转换为
ArrayList

我无法从JLS中调出特定的段落来支持这一点,因此这是一条注释,但如果内存为Java 8服务,则扩展了可以执行的推理类型,我相信通过允许搜索超类型和/或考虑额外的上下文。您的第三个代码段在Java8中编译时没有任何问题。