0. 引言
最近工作中正式环境调用arrayList.remove方法时报错java.lang.UnsupportedOperationException
但是在本地和测试环境都没有报错,发布到正式环境报错了。特记录下,以供后续参考
1. 源码List idList = new ArrayList();
idList.addAll(Func.toLongList(ids));
idList.remove(id);
2. 解决
首先观察Func.toLongList的源码,返回的是Arrays.asList
public static List toLongList(String str) {
return Arrays.asList(toLongArray(str));
}
Arrays.asList的对象类型为java.util.Arrays.ArrayList,是不支持remove和add的,所以我特意在第一行将其初始化为java.util.ArrayList
观察jdk源码发现addAll也没什么问题,关键在于本地和测试环境都正常,但正式环境确实remove报错。于是怀疑正式环境中addAll后被转换为了java.util.Arrays.ArrayList,那测试环境为什么没有转换呢?只有一个原因:jdk不一致
让运维查询了下,还真是,测试环境jdk13,本地jdk1.8.0_312(ARM),正式环境jdk1.8.0_301.
正式这个小版本的差距,导致了问题
于是将原代码调整为
List idList = new ArrayList(Func.toLongList(ids));
idList.remove(id);
问题解决
3. 警醒这个问题也警醒我们测试环境和生产环境一定要保持一致,否则会浪费很多时间在一些难以排查的错误上。我这里还好运气好,没花多少时间想到了环境的问题,如果没注意到这点,不知道要花多少时间才能排查到