java.util.ArrayList 长度和尺寸不同?

java.util.ArrayList length and size different?

我收到有关以下代码行的定期崩溃报告:

myList.get(myList.size() - 1)

如果没有堆栈跟踪,这将不会那么有趣:

java.lang.ArrayIndexOutOfBoundsException: length=22; index=-1
java.util.ArrayList.get ArrayList.java:439
com.myapp.ope.api.ApiManager.onResponse ApiManager.java:215
retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall.lambda$onResponse[=12=]$DefaultCallAdapterFactory$ExecutorCallbackCall DefaultCallAdapterFactory.java:89
retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$hVGjmafRi6VitDIrPNdoFizVAdk.run Unknown Source:6

这似乎意味着 myList 的长度为 22。那么索引如何计算为 -1(这意味着 .size() 会报告 0)?

ArrayList 在内部由数组支持,它会根据需要动态调整内部数组,并且 size 变量在您添加元素时保持不变(在添加元素时递增,在删除时递减元素)。

说在某些时候 ArrayList 的底层数组长度为 22(可能是空数组,即没有存储元素),当您尝试使用 -1 索引访问它时,它会抛出 java.lang.ArrayIndexOutOfBoundsException

*在访问列表之前尝试打印列表大小,并查看大小是否为 0

Java8中的ArrayList只检查索引是否大于它的大小,如果是则抛出一个IndexOutOfBoundsException。否则 array[index] 用于访问用于存储列表元素的数组的所需元素。如果索引超出范围,这将抛出 ArrayIndexOutOfBoundsException,使用消息中数组的长度。如果需要,数组将被替换为更大的数组,但永远不会更改为更小的数组 - 因此数组大于所需的数组是正常的。

在 Java9 中,索引检查已更改:它使用 Objects.checkIndex(),它检查两个限制并使用异常消息列表的大小。