首先我们来看一下下面这段代码:
看看运行结果:
看着没问题,但此时注意这段代码我是把第15行的list.add(4)注释了,那么如果我此时把这一行注释给打开,看看运行结果是否有问题。
运行结果:
直接报了一个异常信息。那么这时候我们就要追踪到底是哪里出现了问题。
肯定是15行注释搞得鬼,那么我们现在就研究一下第15行代码list.add(4),15行的list对象是从上一行Arrays.list()返回的,那我们就定位到第14行,然后我们直接进入看该方法的源码。
我们可以定位到第14行,然后按住Crtl键然后鼠标左键点击进去,也可以最快速的方法就是直接点击鼠标的滚轮,就可以跳进去看源码。
源码:
可以看到new了一个ArrayList(),继续点ArrayList<>进去看看。
这时候我们发现,这个ArrayList它new出来的其实是Arrays这个类里面的静态内部类,也不是下面这个ArrayList
所以Arrays.asList(T ... a)这句代码new的是一个Arrays类里面的静态内部类ArrayList,那调用add方法的时候,我们看一下内部类ArrayList的add()方法究竟发生了啥。
这时候我们在内部类ArrayList找了一圈发现,并没有出现add()方法,所以我们就看父类,它继承了AbstractList
那么它调用的add()就是调用父类AbstractList的add()方法,我们看看AbstractList的add()方法。
继续点进去add(size(),e),看看里面发生了啥。
可以看到这个异常就是我们运行结果在控制台的异常。
所以我们就知道了,喔~原来是因为Arrays.asList()返回的是Arrays类里面静态内部类ArrayList对象,这个内部类里面没有对add()方法进行重写,所以调用的是父类AbstractList的add()方法,而父类AbstractList的add()方法就是会直接throw new UnsupportedOperationException();
那为什么我们直接new一个ArrayList,然后调用add()方法就没事呢?我们同样也是看源码。
我们可以看到当我们直接new一个ArrayList的时候,new出来的是java.util包下的ArrayList
我们可以看到它也是继承了AbstractList
但是我们看看java.util.ArrayList是否自己有重写了add()方法。crtl+F搜索。
发现确实本身是有重写的,那么调用的就不是父类AbstractList的add()方法了,也就不会发生异常了。
总结:
Arrays.asList(T ... a)返回的是java.utli.Arrays类里面的静态内部类ArrayList,这个静态内部类没有重写add()方法,调用的是父类AbstractList的add()方法,父类AbstractList的add()方法会直接抛出异常。
直接new ArrayList()返回的是java.util.ArrayList,这个ArrayList有重写add()方法。
最后:
如果大家觉得这篇文章对你们有所帮助的话,可以给个免费的赞赞,谢谢,也祝各位码农在IT的道路上高歌猛进!