java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!

首先我们来看一下下面这段代码:

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第1张图片

看看运行结果:

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第2张图片

看着没问题,但此时注意这段代码我是把第15行的list.add(4)注释了,那么如果我此时把这一行注释给打开,看看运行结果是否有问题。

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第3张图片

运行结果:

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第4张图片

直接报了一个异常信息。那么这时候我们就要追踪到底是哪里出现了问题。

肯定是15行注释搞得鬼,那么我们现在就研究一下第15行代码list.add(4),15行的list对象是从上一行Arrays.list()返回的,那我们就定位到第14行,然后我们直接进入看该方法的源码。

我们可以定位到第14行,然后按住Crtl键然后鼠标左键点击进去,也可以最快速的方法就是直接点击鼠标的滚轮,就可以跳进去看源码。

源码:

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第5张图片

可以看到new了一个ArrayList(),继续点ArrayList<>进去看看。

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第6张图片

这时候我们发现,这个ArrayList它new出来的其实是Arrays这个类里面的静态内部类,也不是下面这个ArrayList

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第7张图片

所以Arrays.asList(T ... a)这句代码new的是一个Arrays类里面的静态内部类ArrayList,那调用add方法的时候,我们看一下内部类ArrayList的add()方法究竟发生了啥。

这时候我们在内部类ArrayList找了一圈发现,并没有出现add()方法,所以我们就看父类,它继承了AbstractListjava中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第8张图片

那么它调用的add()就是调用父类AbstractList的add()方法,我们看看AbstractList的add()方法。

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第9张图片

继续点进去add(size(),e),看看里面发生了啥。

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第10张图片

可以看到这个异常就是我们运行结果在控制台的异常。

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第11张图片

所以我们就知道了,喔~原来是因为Arrays.asList()返回的是Arrays类里面静态内部类ArrayList对象,这个内部类里面没有对add()方法进行重写,所以调用的是父类AbstractList的add()方法,而父类AbstractList的add()方法就是会直接throw new UnsupportedOperationException();

那为什么我们直接new一个ArrayList,然后调用add()方法就没事呢?我们同样也是看源码。

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第12张图片

我们可以看到当我们直接new一个ArrayList的时候,new出来的是java.util包下的ArrayList

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第13张图片

我们可以看到它也是继承了AbstractList

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第14张图片

但是我们看看java.util.ArrayList是否自己有重写了add()方法。crtl+F搜索。

java中使用Arrays.asList(T ... a)容易踩add(T t)的坑!!_第15张图片

发现确实本身是有重写的,那么调用的就不是父类AbstractList的add()方法了,也就不会发生异常了。

总结:

Arrays.asList(T ... a)返回的是java.utli.Arrays类里面的静态内部类ArrayList,这个静态内部类没有重写add()方法,调用的是父类AbstractList的add()方法,父类AbstractList的add()方法会直接抛出异常。

直接new ArrayList()返回的是java.util.ArrayList,这个ArrayList有重写add()方法。

最后:

如果大家觉得这篇文章对你们有所帮助的话,可以给个免费的赞赞,谢谢,也祝各位码农在IT的道路上高歌猛进!

你可能感兴趣的:(java,开发语言)