最近,我遇到了导致ArrayIndexOutOfBoundsExceptionon的意外错误(不是我的代码)ArrayList#contains。此处的相关代码如下。private static final List<String> list = new ArrayList<>();static void register() { update(); new Timer().schedule(new TimerTask() { @Override public void run() { update(); } }, 0, 21600000);}private static void update() { list.clear(); new Thread(() -> { List<String> other; //should always be the same length. list.addAll(other); }).start();}public static boolean contains(String string) { //called long after register return list.contains(string); //throws ArrayIndexOutOfBounds}我很清楚这ArrayList不是线程安全的,可以使用来修复它Collections#synchronizedList。我的问题是了解此特定代码如何引发ArrayIndexOutOfBoundsException。异常的stacktrace标识中的以下代码ArrayList#indexOf。for (int i = 0; i < size; i++) if (o.equals(elementData[i])) //here return i;在我看来,这只有在size大于时才会发生elementData.length。据我了解,ArrayList#clear实际上并没有减少支持数组的长度。到的调用addAll仅应增加其容量,并且size在扩展数组之后始终会对其进行更新。我看不到在size大于阵列容量的状态下怎么回事。我注意到的一个特定细节是上的延迟Timer为0,这意味着update()快速连续调用了两次。我最好的猜测是,addAll调用在某种程度上是重叠的,这使列表成为某种混合的无效状态。如果有人可以解释这里发生的事情,那就太好了!
添加回答
举报
0/150
提交
取消