1700443640
1700443641
//存储列表元素的数组
1700443642
1700443643
private final E[]a;
1700443644
1700443645
//唯一的构造函数
1700443646
1700443647
ArrayList(E[]array){
1700443648
1700443649
if(array==null)
1700443650
1700443651
throw new NullPointerException();
1700443652
1700443653
a=array;
1700443654
1700443655
}
1700443656
1700443657
/*其他方法省略*/
1700443658
1700443659
}
1700443660
1700443661
这里的ArrayList是一个静态私有内部类,除了Arrays能访问外,其他类都不能访问。仔细看这个类,它没有提供add方法,那肯定是父类AbstractList提供了,来看代码:
1700443662
1700443663
public boolean add(E e){
1700443664
1700443665
throw new UnsupportedOperationException();
1700443666
1700443667
}
1700443668
1700443669
父类确实提供了,但没有提供具体的实现(源代码上是通过add方法调用add(int, E)方法来实现的,为了便于讲解,此处缩减了代码),所以每个子类都需要自己覆写add方法,而Arrays的内部类ArrayList没有覆写,因此add一个元素就会报错了。
1700443670
1700443671
我们再深入地看看这个ArrayList静态内部类,它仅仅实现了5个方法:
1700443672
1700443673
size:元素数量。
1700443674
1700443675
toArray:转化为数组,实现了数组的浅拷贝。
1700443676
1700443677
get:获得指定元素。
1700443678
1700443679
set:重置某一元素值。
1700443680
1700443681
contains:是否包含某元素。
1700443682
1700443683
对于我们经常使用的List.add和List.remove方法它都没有实现,也就是说asList返回的是一个长度不可变的列表,数组是多长,转换成的列表也就是多长,换句话说此处的列表只是数组的一个外壳,不再保持列表动态变长的特性,这才是我们要关注的重点(虽然此处JDK的设计有悖OO设计原则,但这不在我们讨论的范围内,而且我们也无力回天)。
1700443684
1700443685
有些开发者特别喜欢通过如下方式定义和初始化列表:
1700443686
1700443687
List<String>names=Arrays.asList(“张三”,“李四”,“王五”);
1700443688
1700443689
一句话完成了列表的定义和初始化,看似很便捷,却深藏着重大隐患—列表长度无法修改。想想看,如果这样一个List传递到一个允许add操作的方法中,那将会产生何种结果?如果读者有这种习惯,请慎之戒之,除非非常自信该Lis只用于读操作。
[
上一页 ]
[ :1.70044364e+09 ]
[
下一页 ]