那些年踩过的坑之Arrays.asList
一、前言
熟悉开发的兄弟都知道,在写新增和删除功能的时候,大多数时候会写成批量的,原因也很简单,批量既支持单个也支持多个对象的操作,事情也是发生在这个批量方法的调用上,下面我简单说一下这个事情。
二、场景描述
批量方法的参数可能是一个list集合,里面存放了多个待操作的数据,这是批量方法。当我们操作单个对象的时候,也需要调用批量,那传参的时候,就涉及到把单个对象封装成集合,那么封装的方式有几种,我下边罗列一下。
@Testpublic void listTest(){String code = "ITEM-001";//方式1batchOperate(Arrays.asList(code));//方式2batchOperate(Collections.singletonList(code));//方式3batchOperate(CollectionUtil.newArrayList(code));}
我罗列了3种方式,但是我见过最多的就是使用第一种方式Arrays.asList(code),如果用了第一种的话,此时IDEA会给个小黄标提示,有点代码洁癖的人,会按照IDEA推荐的方式进行进一步修改,也就是我们第二种方式Collections.singletonList(code)。
对于我个人来说,我推荐用第三种,而且我本人也是使用第三种传参方式,下面我们运行一下代码,首先我们来看一下第一种传参方式。
通过运行代码,居然报add方法报错,是不是脑瓜子嗡嗡的?我们打个断点看一下,如下图所示,我们发现此时进行add方法的list是不是有点奇怪,不是我们常见的java.util下的ArrayList呀,为了更清晰,我们再深入一下,看看Arrays.asList是怎么一回事。
进入到Arrays源码中,我们看到此ArrayList非彼ArrayList,而是Arrays的一个内部类,而且再仔细看看,发现这个内部类中居然没有add方法,但是确真真实实调用了add方法,它没有的话,应该是它所继承的父类中有add方法,我们继续进入到父类AbstractList中一探究竟。
在AbstractList中,我们终于把add方法给揪出来了,从截图中可以看到,add方法中直接抛出了throw new UnsupportedOperationException(),这也就解释了为什么在调用add方法的时候报错了。
来我们继续再看下一个Collections.singletonList(code)是怎么个情况
果然,也报错了,而且报的错都一样,那么原因和刚才也大差不差。我们再点进去看看源码是什么样的。
通过截图,我们可以看到,SingletonList也是Collections的一个内部类,而且也没有add方法,并且也继承自AbstractList,这时候就很明确了,调用add方法就会直接报错。我们顺便再看看其他的操作方法(如下图所示),基本上也都是报错,说明继承自AbstractList的子类是不允许对集合进行操作的。
最后再看一下小永哥的选择测试结果会怎么样(希望不会翻车......)
通过测试截图可以看到,没毛病,情况我们就分析到这里了。日常开发过程中应该用哪一种我想现在已经很明确了。
三、焦点访谈
T哥:小永哥,有没有人说你很装呢?
小永哥:好像除了你之外,还没有。
T哥:你说的这三种传参有什么意义吗?随便一种都行吧,像你说的那种情况基本上不可能发生。
小永哥:你说的有你的道理,但是谁能保证自己调用的方法都是自己写的,绝对安全可靠,我把参数传过去,人家想这么处理,完全不是我能控制的,但是因为传参的问题导致了报错,是不是得排查,为什么能一次性搞定的东西,要继续浪费时间和精力去处理呢?
T哥,这次算你有道理.........
四、结语
我分享的这些绝不是为了装,像这种看似简单,但是平时不常见的错误,解决不也得花时间吗,如果是生产环境报错,那排查、定位、解决花费的时间更多,有这功夫,我们摸会鱼,喝点咖啡它不香嘛。
今天就分享到这里,谢谢大家,晚安。