什么导致ArrayIndexOutOfBoundsException?
如果您将变量视为可以放置值的“盒子”,那么数组就是一系列彼此相邻放置的盒子,其中盒子的数量是一个有限且明确的整数。
像这样创建一个数组:
final int[] myArray = new int[5]
创建一行 5 个框,每个框都有一个 int。每个盒子都有一个索引,即在一系列盒子中的位置。该索引从 0 开始,到 N-1 结束,其中 N 是数组的大小(框数)。
要从这一系列框中检索其中一个值,您可以通过它的索引来引用它,如下所示:
myArray[3]
这将为您提供系列中第 4 个框的值(因为第一个框的索引为 0)。
ArrayIndexOutOfBoundsException 是由于尝试检索一个不存在的“盒子”、传递的索引高于最后一个“盒子”的索引或为负数而引起的。
在我的运行示例中,这些代码 sn-ps 会产生这样的异常:
myArray[5] //tries to retrieve the 6th "box" when there is only 5
myArray[-1] //just makes no sense
myArray[1337] //waay to high
如何避免ArrayIndexOutOfBoundsException
为了防止ArrayIndexOutOfBoundsException,有几个关键点需要考虑:
循环
在遍历数组时,请始终确保您检索的索引严格小于数组的长度(框数)。例如:
for (int i = 0; i < myArray.length; i++) {
注意<,切勿在其中混入=..
你可能想做这样的事情:
for (int i = 1; i <= myArray.length; i++) {
final int someint = myArray[i - 1]
别这样。坚持上面那个(如果你需要使用索引的话),它会为你省去很多痛苦。
如果可能,请使用 foreach:
for (int value : myArray) {
这样您就不必考虑索引了。
循环时,无论你做什么,都不要改变循环迭代器的值(这里:i)。这应该改变值的唯一地方是保持循环继续。否则更改它只会冒异常的风险,并且在大多数情况下是不必要的。
检索/更新
在检索数组的任意元素时,始终检查它是否是数组长度的有效索引:
public Integer getArrayElement(final int index) {
if (index < 0 || index >= myArray.length) {
return null; //although I would much prefer an actual exception being thrown when this happens.
}
return myArray[index];
}