麻烦初始化List <object []>使用Arrays.asList

时间:2016-10-06 06:59:24

标签: java list generics

当我初始化List时,我能够这样做:

List<Object[]> foo = new ArrayList<>();
foo.add(new Object[]{816, "foo", 2.6});

但是当我想使用Arrays.asList来简化它时:

List<Object[]> bar = Arrays.asList(new Object[]{"bar", 286});

无法编译错误:

incompatible types: inference variable T has incompatible bounds
equality constraints: java.lang.Object[]
lower bounds: java.lang.Object

为什么它不能做类型推断权以及如何解决这个问题?

7 个答案:

答案 0 :(得分:13)

当您将引用类型数组传递给Arrays.asList时,您会获得该引用类型的List

因此,Arrays.asList(new Object[]{"bar", 286})会返回List<Object>,而不是List<Object[]>

答案 1 :(得分:12)

请记住,foo("hello", 1); 只是数组参数的语法糖。您可以使用

调用具有可变参数foo(new Object[]{"hello", 1}); 的方法
Arrays.asList(new Object[]{"bar", 286})

Object

因为编译器无论如何构造第二个表单。

因为当编译器推断类型时没有考虑接收器类型,所以它会查看Object[]并认为你的意思是创建List<Object[]> bar = Arrays.<Object[]>asList(new Object[]{"bar", 286}); 的列表,而不是<Object[]>的单个列表1}}。

使用现有语法的最简单方法是添加显式类型参数:

{ Error: ENOENT: no such file or directory, open '../dist/index.html'
    at Error (native)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '../dist/index.html' }

添加console.log("Build HTML error")告诉编译器应该是什么。

答案 2 :(得分:7)

如果你的列表中只有一个元素,Collections.singletonList(new Object[] {...})是一个更好的选择,因为它避免了varargs并使得在呼叫站点的行为更加明显。

答案 3 :(得分:4)

问题是Arrays.asList是一个varargs方法,它在技术上接收包含参数的数组,并且由于与前泛型代码的兼容性仍然接受数组而不是参数列表。传递单个数组时,调用是不明确的,并且会像pre-varargs方法调用一样处理。

如果您有多个参数,问题就会消失:

List<Object[]> bar = Arrays.asList(new Object[]{"bar", 286}, new Object[]{"baz", 123});

如果只有一个参数,则可以通过插入显式列表元素类型来帮助编译器:

List<Object[]> bar = Arrays.<Object[]>asList(new Object[]{"bar", 286});

或者,您可以使用

List<Object[]> bar = Collections.singletonList(new Object[]{"bar", 286});

创建一个大小为一的不可变列表。请注意,这与Arrays.asList不同,因为后者会返回固定大小的列表,但仍可通过set进行更改。

答案 4 :(得分:2)

Arrays#asList签名:

public static <T> List<T> asList(T... a)

返回类型为List<T>。现在你应该问自己什么是T

TObject,因此返回类型为List<Object>,而非List<Object[]>

答案 5 :(得分:1)

您的电话:

Arrays.asList(new Object[]{"bar", 286});

Object[]创建一个列表。因此,数据转换为新的List<Object>

所以Arrays.asList(new Object[]{"bar", 286}).get(0);将返回&#34; bar&#34;。

在此电话会议中:

List<Object[]> foo = new ArrayList<>();
foo.add(new Object[]{816, "foo", 2.6});

您正在创建List<Object[]>(2D维)并在其后面添加一个元素:foo.add(..);。 因此,您要添加一个由Object[]组成的元素。 如果您现在致电foo.get(0);,您将获得Object[],其中包括: 816,&#34; foo&#34;,2.6

我想你想做:

Object[] oa = new Object[]{""};
Object[] ob = new Object[]{""};
List<Object[]> list = Arrays.asList(oa, ob);

如果您有任何疑问,请随时问我:)

答案 6 :(得分:1)

当你使用List<Object[]> bar = Arrays.asList(new Object[]{"bar", 286});时,你实际上有一个二维数组,你可以通过List<Object[]> bar = Arrays.asList(new Object[][]{new Object[]{"bar","asd",123}}); 来解决这个问题