【问题标题】:trouble initialize List<Object[]> Using Arrays.asList麻烦初始化 List<Object[]> 使用 Arrays.asList
【发布时间】:2016-10-06 06:59:23
【问题描述】:

当我初始化 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

为什么它不能正确地进行类型推断以及如何解决这个问题?

【问题讨论】:

标签: java list generics


【解决方案1】:

请记住,... 只是数组参数的语法糖。您可以使用可变参数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});

添加 &lt;Object[]&gt; 告诉编译器 T 应该是什么。

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

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

【讨论】:

    【解决方案2】:

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

    因此Arrays.asList(new Object[]{"bar", 286}) 返回List&lt;Object&gt;,而不是List&lt;Object[]&gt;

    【讨论】:

      【解决方案3】:

      如果您的列表中只有一个元素,Collections.singletonList(new Object[] {...}) 是更好的选择,因为它避免了可变参数并使调用站点的行为更加明显。

      【讨论】:

        【解决方案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 更改。

        【讨论】:

          【解决方案5】:

          Arrays#asList签名:

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

          返回类型为List&lt;T&gt;。现在你应该问问自己T是什么?

          TObject,因此返回类型将是List&lt;Object&gt;,而不是List&lt;Object[]&gt;

          【讨论】:

            【解决方案6】:

            您的电话:

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

            Object[] 创建一个列表。所以数据被转换成一个新的List&lt;Object&gt;

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

            在本次通话中:

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

            您正在创建一个List&lt;Object[]&gt;(二维)并在其后添加一个元素:foo.add(..);。 因此,您要添加一个由Object[] 组成的元素。 如果您现在拨打foo.get(0);,您将获得Object[],其中包括: 816,“富”,2.6

            我想你想这样做:

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

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

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                猜你喜欢
                • 2012-05-30
                • 1970-01-01
                • 1970-01-01
                • 2012-12-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多