初始化List<Object[]>时出现问题,使用Arrays.asList。

14

当我初始化列表时,我可以这样做:

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

为什么它无法正确进行类型推断,如何解决?

相关:https://dev59.com/FHM_5IYBdhLWcg3wvV5w - user180100
2
作为一个经验法则,永远不要混合使用泛型和数组。(一旦你理解了为什么这是一个好的经验法则,你可以忽略这个规则。) - Daniel Pryden
7个回答

14

请记住,...只是数组参数的语法糖。您可以使用可变参数foo(Object...)调用方法,方法如下:

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[]> 告诉编译器 T 应该是什么。

或者,如果您不需要列表可变:

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

13

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

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


7
如果你的列表只有一个元素,Collections.singletonList(new Object[] {...}) 是更好的选择,因为它避免了varargs并使调用位置的行为更加明显。

4
问题在于Arrays.asList是一个可变参数方法,它在技术上接收包含参数的数组,并由于与预泛型代码的兼容性而仍然接受数组而不是参数列表。当传递单个数组时,调用是模棱两可的,并将被处理为先前的非可变参数方法调用。
当有多个参数时,问题消失了:
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});

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


2

Arrays#asList签名:

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

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

TObject,因此返回类型将是List<Object>,而不是List<Object[]>


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

1
你的电话:
Arrays.asList(new Object[]{"bar", 286});

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

因此,Arrays.asList(new Object[]{"bar", 286}).get(0);将返回"bar"。

在这个调用中:

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

你正在创建一个List<Object[]>(二维数组),并在其中添加一个元素:foo.add(..);。 因此,您正在添加一个由Object[]组成的元素。 如果现在调用foo.get(0);,您将得到一个由以下内容组成的Object[]: 816,“foo”,2.6
我认为您想要做的是:
Object[] oa = new Object[]{""};
Object[] ob = new Object[]{""};
List<Object[]> list = Arrays.asList(oa, ob);

如果您有问题,请随时问我 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接