栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Arrays.asList的一些坑

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Arrays.asList的一些坑

结论
    Arrays.asList() 对基本数据类型支持不友好,会把基本数据类型数组仿作一个参数。Arrays.asList() 的参数改变后,结果得到得到 List 的值也会改变。Arrays.asList() 的结果为Arrays的一个内部类,而不是 java.util.ArrayList;并且不可编辑。
测试
public class ArraysUTest {
 
    @Test
    public void asListUTest() {
        int[] ints = new int[]{1, 2 , 3 , 4 , 5 , 6};
        List intList = Arrays.asList(ints);
        System.out.println("Arrays::asList 参数为基本数据类型数组:");
        print(intList);

        ints[0] = 99999;
        System.out.println("改变基本类型数组后,转换的 List 结果的值:");
        print(intList);

        Integer[] integers = {1, 2, 3};
        List integerList = Arrays.asList(integers);
        System.out.println("Arrays::asList 参数为引用类型数组:");
        print(integerList);

        integers[0] = 9999;
        System.out.println("改变引用类型数组后,转换的 List 结果的值:");
        print(integerList);
 
        System.out.println("Arrays::asList 结果的类型为:");
        System.out.println(integerList.getClass());
    }
 
    private void print(List intList) {
        for (Object obj : intList) {
            System.out.println(obj.getClass() + "t" + (obj.getClass().isArray() ? Arrays.toString((int[])obj) : obj));
        }
        System.out.println();
    }
}
分析

先来看第二点和第三点: Arrays.asList() 实现如下:

    
    @SafeVarargs
    @SuppressWarnings("varargs")
    public static  List asList(T... a) {
        return new ArrayList<>(a);
    }

其中,ArrayList是Arrays的内部类:java.util.Arrays$ArrayList。

private static class ArrayList extends AbstractList
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
        }
        // 其他实现...
    }

可以看到,这个java.util.Arrays$ArrayList直接将传入的参数数组(T... a,记为T [])保存为内部数组,使用的是同一个内存地址。所以,当数组(T[])本身改变的时候,也会同时影响到java.util.Arrays$ArrayList内部保存的数组变量。

至于第一点,则是泛型使用的限制之一:Java泛型不能使用基本类型 举个简单的例子:

List list = new List();// 编译前类型检查报错

泛型在编译时,会进行类型擦除,最后只保留原始类型。而原始类型只能是Object类及其子类,因此不能使用基本数据类型。 所以,Arrays.asList() 并不认识基本数据类型 int,它只把 int[].class当成了一个基础类型。因此下面一段代码的结果也不难猜测:

    @Test
    public void testP() {
        int[] ints = {1, 2, 3};
        System.out.println("基本数据类型数组:");
        f(ints);

        Integer[] integers = {1, 2, 3};
        System.out.println("封装数据类型数组:");
        f(integers);
    }

    private  void f(T... p) {
        for (T t : p) {
            System.out.println(t);
        }
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/708516.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号