修复线上问题,又造成了个Bug

项目场景

这是一位朋友给我分享的实际线上问题,看似简单却害了项目再次造出一个bug来。

场景:线上环境中,需要查询某某业务数据,条件是状态,之前产品只要求查两个状态的,但现在让他再多查一个状态的。

自信满满的他,以为就加个状态,肯定没问题的。

在代码中,这位朋友用到了Arrays工具类。

写法如下:

List<Integer> statusList= Arrays.asList(0,1);

这里看起来没问题。

第一种想到的就是直接加个状态就搞定了。

List<Integer> statusList= Arrays.asList(0,1,2);

但是,他定义的statusList在方法也有个查询用到了!

为了不影响其他部分代码,于是,他就是这么干的:

List<Integer> statusList= Arrays.asList(0,1);
statusList.add(2);

就加了一行代码,非常非常简单,没有任何逻辑。

并且,本地编译也没问题,自信满满的,和领导说,改好了,可以上线了。

可是,一上线就大量报错:

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.AbstractList.add(AbstractList.java:153)
	at java.base/java.util.AbstractList.add(AbstractList.java:111)

懵了呀,这!怎么可能报错,我就往List中加了一条数据而已。

哎,今年的年终奖估计是无望了,可是自己却觉得自己很无辜。

问题分析

分析上述代码:

List<Integer> statusList= Arrays.asList(0,1);
statusList.add(2);

进入asList方法:

   public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

返回了一个ArrayList,凭我们的经验,向这个list里面add一个元素肯定没问题。

但是,为什么会报错呢?

其实,这里的ArrayList,并非我们平常说的ArrayList。

这里的ArrayList是Arrays中内部类。

ArrayList的基本定义:

private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable {
        // ......
    }

使用快捷键Alt+7查看内部类ArrayList主要包含哪些方法?

到这里,我们可以发现,ArrayList里完全没有add方法,也就是说这里的内部类ArrayList是不支持add的。

再回到上面说的报错异常:UnsupportedOperationException

AbstractList中add报错的

 public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

总结

Arrays.asList返回的List是Arrays中内部类。该内部类ArrayList继承了AbstractList但未重写父抽象类里面的add和remove方法。

因此,调用add、remove方法实际上是调用了父类AbstractList中的方法。

查看AbstractList发现这几个都未具体实现,直接返回了不支持操作异常即UnsupportedOperationException异常!

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public E remove(int index) {
        throw new UnsupportedOperationException();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小Java开发者

“是一种鼓励,你懂的”

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值