ArrayIndexOutOfBoundsException
是什么意思,我该如何解决它?
以下是触发异常的代码示例:
String[] names = { "tom", "bob", "harry" };
for (int i = 0; i <= names.length; i++) {
System.out.println(names[i]);
}
ArrayIndexOutOfBoundsException
是什么意思,我该如何解决它?
以下是触发异常的代码示例:
String[] names = { "tom", "bob", "harry" };
for (int i = 0; i <= names.length; i++) {
System.out.println(names[i]);
}
你需要首先查看文档,其中已经比较清楚地解释了:
抛出此异常表示使用非法索引访问了数组。索引要么为负数,要么大于等于数组大小。
例如:
int[] array = new int[5];
int boom = array[10]; // Throws the exception
关于如何避免这种情况...嗯,不要那样做。小心处理数组下标。
有时人们会遇到一个问题,认为数组是从1开始的,例如:
int[] array = new int[5];
// ... populate the array here ...
for (int index = 1; index <= array.length; index++)
{
System.out.println(array[index]);
}
这段代码将会忽略第一个元素 (索引 0),当索引为 5 时会抛出异常。有效的索引范围应该是 0-4(包含 0 和 4)。这里正确、惯用的for
语句应该是:
for (int index = 0; index < array.length; index++)
(这是假设你当然需要使用索引,在这种情况下。如果可以使用增强型for循环,那就使用它吧。)
(That's assuming you need the index, of course. If you can use the enhanced for loop instead, do so.)
for (int nestedIndex = 0; nestedIndex < array[outerIndex].length; nestedIndex++) { ... array[outerIndex][nestedIndex] ... }
。 - Andrey基本上:
if (index < 0 || index >= array.length) {
// Don't use this index. This is out of bounds (borders, limits, whatever).
} else {
// Yes, you can safely use this index. The index is present in the array.
Object element = array[index];
}
根据您的具体情况,
for (int i = 0; i<=name.length; i++)
索引包括数组的长度。这是越界了。你需要用<
替换<=
。
for (int i = 0; i < name.length; i++)
以下是这篇优秀文章的内容:for循环中的ArrayIndexOutOfBoundsException
简单来说:
在最后一次迭代中,
for (int i = 0; i <= name.length; i++) {
i
的值将等于 name.length
,这是一个不合法的索引,因为数组索引是从零开始的。for (int i = 0; i < name.length; i++)
^
这意味着你正在尝试访问一个数组的索引,但该索引不在有效范围内。
例如,这将使用上限为4来初始化一个原始整数数组。
int intArray[] = new int[5];
程序员从零开始计数。例如,这个循环会抛出一个 ArrayIndexOutOfBoundsException
异常,因为上限是4而不是5。
intArray[5];
什么导致了ArrayIndexOutOfBoundsException
?
如果你把一个变量想象成一个“盒子”,你可以在里面放置一个值,那么数组就是一系列相邻放置的盒子,盒子的数量是有限且明确的整数。
创建这样的数组:
final int[] myArray = new int[5]
创建了一个包含5个元素的一维数组,每个元素都是int
类型。每个元素都有一个索引,即它在数组中的位置。这个索引从0开始,到N-1结束,其中N是数组的大小(即元素的数量)。
要访问这个数组中的某个元素,可以通过其索引进行引用,例如:
myArray[3]
这将为您提供系列中第4个框的值(因为第一个框的索引为0)。
尝试通过传递高于最后一个“框”的索引或负数的索引来检索不存在的“框”,会导致ArrayIndexOutOfBoundsException
。
对于我的运行示例,这些代码片段会产生这样的异常:
myArray[5] //tries to retrieve the 6th "box" when there is only 5
myArray[-1] //just makes no sense
myArray[1337] //way 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];
}
for
语句。for
在数组中向后移动或仅迭代每隔一个元素。for
。String[] name = {"tom", "dick", "harry"};
for(int i = 0; i< name.length; i++) {
System.out.print(name[i] + "\n");
}
...与此等价:
String[] name = {"tom", "dick", "harry"};
for(String firstName : name) {
System.out.println(firstName + "\n");
}
name.length
给出了你的字符串对象数组中的字符串对象数量,即3个,但是你只能访问索引2以及以下的元素name[2]
,
因为数组可以从索引0到name.length - 1
进行访问,这里你将获得name.length
个对象。for
循环时,你也从索引零开始,并应该以name.length - 1
结束。在一个数组a[n]中,你可以访问a[0]到a[n-1]。String[] a={"str1", "str2", "str3" ..., "strn"};
for(int i=0; i<a.length(); i++)
System.out.println(a[i]);
根据您的情况:
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
System.out.print(name[i] +'\n');
}
对于给定的数组,数组长度为3(即name.length = 3)。但由于它从索引0开始存储元素,因此最大索引为2。
因此,你应该将“i<=name.length”改写为“i<name.length”,以避免“ArrayIndexOutOfBoundsException”异常。
对于这个简单的问题就说到这里,但我想强调Java中一个新特性,这将避免即使对于初学者在数组索引方面的所有困扰。Java-8已为您抽象出了迭代的任务。
int[] array = new int[5];
//If you need just the items
Arrays.stream(array).forEach(item -> { println(item); });
//If you need the index as well
IntStream.range(0, array.length).forEach(index -> { println(array[index]); })
什么是好处呢?首先,就像英文一样易读。其次,您无需担心 ArrayIndexOutOfBoundsException
。
public class MyController {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
public void handleRequest(ServletRequest req, ServletResponse res) {
Date date = dateFormat.parse(req.getParameter("date"));
}
}