Prior to Java 7 the syntax below was used to create an ArrayList,
在Java 7之前,下面的语法用于创建ArrayList,
ArrayList<Integer> ints = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7));
But since Java 7 we can omit the generic type in the constructor i.e.,
但是从Java 7开始我们可以省略构造函数中的泛型类型,即
ArrayList<Integer> ints = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
But when I tried to do something like,
但当我试图做某事时,
ArrayList<Number> nums = new ArrayList<>(Arrays.asList(1,2,3,4,4,5.5,6.6,7.7));
I get an error, but when I mention the generic type on right side i.e.,
我收到错误,但是当我在右侧提到通用类型时,即
ArrayList<Number> nums = new ArrayList<Number>(Arrays.asList(1,2,3,4,5.5,6.6,7.7));
The code works perfectly. What could be the reason behind this ?
代码完美无缺。这背后的原因是什么?
Thanks in Advance.
提前致谢。
2 个解决方案
#1
4
Arrays.asList
is a generic method, so technically, it can be invoked as:
Arrays.asList是一个通用方法,因此从技术上讲,它可以调用为:
Arrays.<Number> asList(1, 2, 3);
Even before Java 7, the language could do some limited inference to eliminate this when the left-hand side was known, as in
甚至在Java 7之前,语言可以做一些有限的推断,以便在左侧知道时消除这种情况,如
final List<Number> nums = Arrays.asList(1, 2, 3);
It looks like you stumbled onto an edge case where the two types of inference cannot be successfully combined, where the diamond inference and generic method inference don't get along. I'm sure the JLS sheds more light on this as well if you were to dig through it.
看起来你偶然发现了两种类型的推理无法成功组合的边缘情况,其中钻石推理和通用方法推理无法相处。我敢肯定,如果你要挖掘它,JLS也会对此有所了解。
#2
3
Java Generics are Invariant whereas Arrays are Covariant.
Java Generics是不变的,而Arrays是Covariant。
If generics in Java were covariant, if A
is a subtype of B
, then List[A]
is a subtype of List[B]
. But it is not the case in Java. ( Scala has a covariance implementation. In Scala, if B
extends A
, then List[B]
extends List[A]
)
如果Java中的泛型是协变的,如果A是B的子类型,则List [A]是List [B]的子类型。但在Java中并非如此。 (Scala有一个协方差实现。在Scala中,如果B扩展A,那么List [B]扩展List [A])
But String[]
is subtype of Object[]
但String []是Object []的子类型
Hence an ArrayList<Double>
cannot be cast to an ArrayList<Number>
as in your case.
因此,无法像您的情况那样将ArrayList
#1
4
Arrays.asList
is a generic method, so technically, it can be invoked as:
Arrays.asList是一个通用方法,因此从技术上讲,它可以调用为:
Arrays.<Number> asList(1, 2, 3);
Even before Java 7, the language could do some limited inference to eliminate this when the left-hand side was known, as in
甚至在Java 7之前,语言可以做一些有限的推断,以便在左侧知道时消除这种情况,如
final List<Number> nums = Arrays.asList(1, 2, 3);
It looks like you stumbled onto an edge case where the two types of inference cannot be successfully combined, where the diamond inference and generic method inference don't get along. I'm sure the JLS sheds more light on this as well if you were to dig through it.
看起来你偶然发现了两种类型的推理无法成功组合的边缘情况,其中钻石推理和通用方法推理无法相处。我敢肯定,如果你要挖掘它,JLS也会对此有所了解。
#2
3
Java Generics are Invariant whereas Arrays are Covariant.
Java Generics是不变的,而Arrays是Covariant。
If generics in Java were covariant, if A
is a subtype of B
, then List[A]
is a subtype of List[B]
. But it is not the case in Java. ( Scala has a covariance implementation. In Scala, if B
extends A
, then List[B]
extends List[A]
)
如果Java中的泛型是协变的,如果A是B的子类型,则List [A]是List [B]的子类型。但在Java中并非如此。 (Scala有一个协方差实现。在Scala中,如果B扩展A,那么List [B]扩展List [A])
But String[]
is subtype of Object[]
但String []是Object []的子类型
Hence an ArrayList<Double>
cannot be cast to an ArrayList<Number>
as in your case.
因此,无法像您的情况那样将ArrayList