- 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 ArrayListextends 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泛型不能使用基本类型 举个简单的例子:
Listlist = 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);
}
}



