ArrayList与ArrayList的故事——记录一次debug

321 阅读2分钟

问题开始于一次对List的操作,当我打算对一个使用数组转换的List进行remove元素操作时,它报出了运行时异常,缠斗了半个小时以后,我打开了源码仔细核对,发现此ArrayList非彼Arraylist...

现在重新写一个例子重现一下当时的问题,以作记录: 如图:代码十分简单,就是利用rt包里的Arrays类将一个对象数组转化为List,在代码编写的过程中编辑器并未发现任何不妥。

如果打开asList方法我们会发现它调用了ArrayList的构造方法来初始化该List对象:

没有仔细观察的话该过程也不存在什么问题,但是实际上我们通常使用的ArrayList类位于java.util工具包下,而且其构造方法包含三个:

1.带有初始化负载因子的构造方法

2.无参构造

3.初始化一个Collection对象的构造方法

结构里展示了所有的构造方法

那么我们在adList中使用的构造方法其实并不是我们平时使用的构造方法,并且使用该方法生成的ArrayList对象并非我们平时自己定义的List对象,而是在Arrays类中的私有内部类: 该类与我们常用的ArrayList名称相同,并且由于其包含了绝对多数与之相同的方法,所以我们在使用过程中并不会感觉到有什么区别,但是,当调用remove方法时,系统在运行时就会抛出异常UnsupportedOperationException: 因为该ArrayList内部类并不含有remove方法来移除元素。 令人非常困惑的是,IDE在预编译时候并不会发现这个问题,而且我们跟踪remove方法会到达util的ArrayList中,也就是说IDE在分析代码时候选择了错误的类定义,但是虚拟机在加载该类时又选择加载了正确的类。

该问题作为一个经验丰富的程序员是肯定可以避免的,但是如果新手遇到此类问题,一定引起注意,切不可在Arrays.asList方法所返回的ArrayList对象中调用remove方法