为什么我可以初始化ArrayList,如下所示:
ArrayList<Integer> x = new ArrayList<Integer>(Arrays.asList(1,2));
但使用时出现错误:
ArrayList<Long> x = new ArrayList<Long>(Arrays.asList(1,2));
如果需要,Java会自动将int
转换为long
。
但是,如果需要从Integer
到Long
的转换,Java不会这样做。
函数Arrays.asList(...)
返回List<E>
,其中E
是用作参数的类型。当你使用1, 2, 3
时,类型是int
。但是,在Java中不可能像List<int>
一样使用数据类型(至少目前)。因此它会自动将int
转换为Integer
并生成List<Integer>
对象。这个过程称为自动装箱,Java可以对所有数据类型执行此操作,以实现相应的对象表示。
如果你现在使用构造函数new ArrayList<Integer>(List<E> list)
,它期望E
是Integer
类型的东西。所以List<Integer>
作为输入。
但是当你使用new ArrayList<Long>(List<E> list)
显然E
需要是Long
类型。然而,对象Integer
不是Long
类型,因此它不接受参数。第一种常见类型的Integer
和Long
是抽象类Number
(也持有Double
,Float
和其他)(documentation)。
所以这一切都围绕输入1, 2, 3
被解释为int
而不是long
。您可以通过明确告诉Java将数字解释为long
来解决此问题,您可以通过在数字后面附加l
或L
来实现:
new ArrayList<Long>(Arrays.asList(1L, 2L, 3L));
现在你收到一个List<Long>
然后被添加到ArrayList<Long>
。
请注意,可以使用相同的技术将十进制数明确解释为float
而不是double
:1.5F
或1.5f
这是因为1
和2
是整体和Arrays.asList(1, 2)
创造了List<Integer>
。
而ArrayList
的复制构造函数要求参数具有相同的泛型类型。
您有几个选项,但最简单的方法是通过添加int
后缀将long
s更改为L
s:
List<Long> x = new ArrayList<Long>(Arrays.asList(1L, 2L));
请注意,使用Java 9,您还可以编写:
List<Long> x = List.of(1L, 2L);
你必须使用文字Long
或l
指定L
数字。
ArrayList<Long> x = new ArrayList<Long>(Arrays.asList(1L, 2L));
因为Arrays.asList(1,2)
将隐含地返回List<Integer>
。
您可以使用以下习语来解决此问题:
ArrayList<Long> x = new ArrayList<Long>(Arrays.asList(1l,2l));