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]);
}
当前回答
我所见过的看似神秘的arrayindexoutofboundsexception最常见的情况,即显然不是由您自己的数组处理代码引起的,是SimpleDateFormat的并发使用。特别是在servlet或控制器中:
public class MyController {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
public void handleRequest(ServletRequest req, ServletResponse res) {
Date date = dateFormat.parse(req.getParameter("date"));
}
}
如果两个线程一起进入SimplateDateFormat.parse()方法,你可能会看到一个ArrayIndexOutOfBoundsException异常。注意SimpleDateFormat类javadoc的同步部分。
确保代码中没有像servlet或控制器那样以并发方式访问线程不安全类(如SimpleDateFormat)的地方。检查servlet和控制器的所有实例变量,寻找可能的可疑对象。
其他回答
根据贵公司守则:
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
System.out.print(name[i] +'\n');
}
如果你检查 System.out.print (name.length);
你会得到3;
也就是说你的名字长度是3
你的循环从0运行到3 它应该是0到2或者1到3
回答
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<name.length; i++) {
System.out.print(name[i] +'\n');
}
ArrayIndexOutOfBounds表示您正在尝试索引数组中未分配的位置。
在这种情况下:
String[] name = { "tom", "dick", "harry" };
for (int i = 0; i <= name.length; i++) {
System.out.println(name[i]);
}
的名字。length是3,因为数组是用3个String对象定义的。 当访问数组的内容时,position从0开始。因为有3个项目,这意味着名字[0]=“tom”,名字[1]=“dick”,名字[2]=“harry” 当你循环时,因为i可以小于或等于name。长度,您正在尝试访问名称[3],该名称不可用。
为了解决这个问题…
In your for loop, you can do i < name.length. This would prevent looping to name[3] and would instead stop at name[2] for(int i = 0; i<name.length; i++) Use a for each loop String[] name = { "tom", "dick", "harry" }; for(String n : name) { System.out.println(n); } Use list.forEach(Consumer action) (requires Java8) String[] name = { "tom", "dick", "harry" }; Arrays.asList(name).forEach(System.out::println); Convert array to stream - this is a good option if you want to perform additional 'operations' to your array e.g. filter, transform the text, convert to a map etc (requires Java8) String[] name = { "tom", "dick", "harry" }; --- Arrays.asList(name).stream().forEach(System.out::println); --- Stream.of(name).forEach(System.out::println);
在代码中,您已经访问了从索引0到字符串数组长度的元素。的名字。Length给出了字符串对象数组中字符串对象的数量,即3,但你只能访问到索引2名称[2], 因为可以从索引0到name访问数组。长度- 1,你得到名字。对象的长度。
即使在使用for循环时,您已经从索引0开始,并且应该以name结束。长度- 1。在数组a[n]中,您可以从[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');
}
数组中的每一项都称为一个元素,每个元素都通过它的数值索引来访问。如上图所示,编号从0开始。例如,第9个元素将因此在索引8处被访问。
抛出IndexOutOfBoundsException表示某种类型的索引(例如数组、字符串或向量)超出了范围。
任意数组X,可以从[0到(X.length - 1)]访问
什么原因导致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++) {
注意<,不要把a =混进去。
你可能想做这样的事情:
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];
}