引言
在Java开发中,数组与集合之间的转换是一个常见的操作。**Arrays.asList()**方法因其简洁的语法和便捷的使用方式,被广泛应用于将数组转换为集合(如List)。
然而,这个看似简单的方法背后却隐藏着一个大坑,如果不小心处理,可能会导致线上事故,本文也是本人自身项目遇到的惨痛经历,希望能够通过讲解这个问题,让大家在实际工作中避开这个坑。
事故回顾
这个问题是出现开发一个电商平台的订单系统时,遇到了类似的问题。需要将一个订单ID数组转换为一个List,并在后续的业务逻辑中向这个List中添加新的订单ID。
由于个人经验不足,使用了Arrays.asList()方法,部署到线上导致在添加新订单ID时抛出了UnsupportedOperationException异常,整个订单处理流程中断,线上系统出现了严重的故障。
影响分析
这次事故对电商平台造成了巨大的影响:
- 用户体验下降: 由于订单处理流程中断,用户无法正常下单,导致用户体验大幅下降。
- 业务中断:订单系统的故障直接影响到了整个电商平台的业务运营,造成了大量的订单积压。
- 经济损失:由于业务中断,平台失去了大量的潜在收入,给公司带来了不小的经济损失。
- 信任危机:频繁的系统故障让用户对平台的信任度下降,可能导致用户流失。
后面也是及时修复,吸取本次事故教训。
事故问题描述
首先先简单描述一下这个事故问题,废话不多说,直接看实际业务代码,也就将一个数组转换为List,并对这个List进行增删操作。
Integer[] arr = {
1, 2};
List<Integer> list = Arrays.asList(arr);
list.add(3);
上述代码看起来,没问题,编译器也没有报错。但是运行这段代码时,会抛出UnsupportedOperationException异常,提示我们不支持添加操作。这究竟是怎么回事呢?
所以这是不是个大坑,如果在实际开发中没有进行自测,必定不会酿成重大线上事故。
问题分析
上述已经知道这个使用Arrays.asList()将数组装换成List会在add情况会报错,接下来深入源码进行分析。
Arrays.asList()的内部实现
Arrays.asList(arr)方法实际上返回的是一个Arrays类的内部类ArrayList,而不是我们常用的java.util.ArrayList。这个内部类ArrayList继承自AbstractList,并没有实现add和remove方法。
Arrays类的内部类ArrayList完整源码如下:
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length