问题:是什么导致java.lang.ArrayIndexOutOfBoundsException,如何防止它?

ArrayIndexOutOfBoundsException是什么意思,我该如何摆脱?

这是触发异常的代码示例:

String[] names = { "tom", "bob", "harry" };
for (int i = 0; i <= names.length; i++) {
    System.out.println(names[i]);
}
标签:java,arrays,exception,indexoutofboundsexception

回答2:

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++) {

回答3:

这篇出色的文章中: for循环中的ArrayIndexOutOfBoundsException

简而言之:

的最后一次迭代中
for (int i = 0; i <= name.length; i++) {

i将等于name.length,这是一个非法索引,因为数组索引是从零开始的。

您的代码应阅读

for (int i = 0; i < name.length; i++) 
                  ^

回答4:

这意味着您正在尝试访问无效的数组索引,因为它不在边界之间。

例如,这将初始化一个上限为4的原始整数数组。

int intArray[] = new int[5];

程序员从零开始计数。因此,例如,由于上限为4而不是5,因此会抛出ArrayIndexOutOfBoundsException

intArray[5];

回答5:

为避免数组索引越界异常,应使用在何时何地可以增强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");
}

回答6:

是什么原因导致ArrayIndexOutOfBoundsException

如果您将变量视为可以放置值的"盒子",则数组是一系列彼此相邻放置的盒子,盒子的数量是有限且显式的整数。

创建这样的数组:

final int[] myArray = new int[5]

创建一行5个框,每个框包含一个int。每个盒子都有一个索引,在一系列盒子中的位置。该索引从0开始,到N-1结束,其中N是数组的大小(盒子的数量)。

要从这一系列框中检索值之一,可以通过其索引引用它,如下所示:

myArray[3]

这将为您提供系列中第4个框的值(因为第一个框的索引为0)。

ArrayIndexOutOfBoundsException是由于尝试通过传递比上一个" box"的索引高或负的索引来检索不存在的" box"而引起的。

在我正在运行的示例中,这些代码段将产生这样的异常:

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];
}

回答7:

在您的代码中,您访问了从索引0到字符串数组长度的元素。 name.length给出了字符串对象数组中字符串对象的数量,即3,但是您最多只能访问索引2 name[2],因为该数组可以可以从索引0到name.length-1进行访问,在这里您可以获得name.length个对象。

即使在使用for循环时,您也从索引0开始,并且应该以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');
}

回答8:

对于给定的数组,数组的长度为3(即name.length = 3)。但是由于它存储从索引0开始的元素,因此具有最大索引2。

因此,应使用" i <** name.length"代替" i ** <= name.length",以避免" ArrayIndexOutOfBoundsException"。

回答9:

这个简单的问题就这么多了,但是我只是想强调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

回答10:

由于i<=name.length部分,您将获得ArrayIndexOutOfBoundsExceptionname.length返回字符串name的长度,即3。因此,当您尝试访问name[3]时,它是非法的,并且引发异常。

已解析的代码:

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i < name.length; i++) { //use < insteadof <=
  System.out.print(name[i] +'\n');
}

它在 Java中定义语言规范

publicfinal字段length,其中包含数组的组件数。 length可以是正数或零。

回答11:

这就是在Eclipse中抛出这种异常时的样子。红色数字表示您尝试访问的索引。所以代码看起来像这样:

myArray[5]

当您尝试访问该数组中不存在的索引时,将引发错误。如果数组的长度为3,

int[] intArray = new int[3];

那么唯一的有效索引是:

intArray[0]
intArray[1]
intArray[2]

如果数组的长度为1,

int[] intArray = new int[1];

那么唯一的有效索引是:

intArray[0]

任何等于数组长度或大于数组长度的整数:超出范围。

任何小于0的整数:超出范围;

PS:如果您希望更好地理解数组并进行一些实际练习,请在此处观看视频:有关Java中的数组的教程

回答12:

对于多维数组,确保访问正确维的length属性可能很棘手。以下面的代码为例:

int [][][] a  = new int [2][3][4];

for(int i = 0; i < a.length; i++){
    for(int j = 0; j < a[i].length; j++){
        for(int k = 0; k < a[j].length; k++){
            System.out.print(a[i][j][k]);
        }
        System.out.println();
    }
    System.out.println();
}

每个维度都有不同的长度,所以一个细微的错误是,中间和内部循环使用相同维度的length属性(因为a[i].lengtha[j].length)相同。

相反,内部循环应使用a[i][j].length(或为简单起见,使用a[0][0].length)。 / p>

回答13:

对于看似神秘的ArrayIndexOutOfBoundsExceptions(即显然不是由您自己的数组处理代码引起的),我所看到的最常见情况是并发使用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和控制器的所有实例变量,以查找可能的可疑对象。

回答14:

ArrayIndexOutOfBoundsException每当此异常即将到来时,这意味着您试图使用超出其范围的数组索引,或者以非专业人员的方式使用的索引所要求的数量比初始化的要多。

为防止这种情况,请始终确保您不请求数组中不存在的索引,即,如果数组长度为10,则索引范围必须在0到9之间

回答15:

ArrayIndexOutOfBounds表示您试图索引未分配的数组中的位置。

在这种情况下:

String[] name = { "tom", "dick", "harry" };
for (int i = 0; i <= name.length; i++) {
    System.out.println(name[i]);
}
  • name.length为3,因为已使用3个String对象定义了数组。
  • 访问数组的内容时,位置从0开始。由于有3个项目,因此将表示name [0] =" tom",name [1] =" dick"和name [2] =" harry
  • 循环时,由于 i 可以小于或等于name.length,因此您正在尝试访问不可用的name [3]。

要解决这个问题...

  • 在for循环中,您可以执行<名称。长度。这样可以防止循环到名称[3],而是停在名称[2]>

    for(inti=0;i

  • 对每个循环使用

    String[]name={"tom","dick","harry"};for(String n:name){System.out.println(n); }

  • 使用list.forEach(消费者操作)(需要Java8)

    String[]name={"tom","dick","harry"};Arrays.asList(name).forEach(System.out :: println);

  • 将数组转换为流-如果要对数组执行其他``操作'',例如,这是一个不错的选择过滤,转换文本,转换为地图等(需要Java8)

    String[]name={"tom","dick","harry"};--- Arrays.asList(name).stream()。forEach(System.out :: println); --- Stream.of(name).forEach(System.out :: println);

回答16:

ArrayIndexOutOfBoundsException意味着您正在尝试访问不存在或超出此数组范围的数组索引。数组索引从 0 开始,以 length-1 结尾。

以您的情况

for(int i = 0; i<=name.length; i++) {
    System.out.print(name[i] +'\n'); // i goes from 0 to length, Not correct
}

ArrayIndexOutOfBoundsException在您尝试访问不存在的name.length索引元素时发生(数组索引以长度-1结尾)。只需将<=替换为<即可解决此问题。>

for(int i = 0; i < name.length; i++) {
    System.out.print(name[i] +'\n');  // i goes from 0 to length - 1, Correct
}

回答17:

对于长度为n的任何数组,该数组的元素的索引范围为0到n-1。

如果您的程序试图访问数组索引大于n-1的任何元素(或内存),则Java会抛出 ArrayIndexOutOfBoundsException

这是我们可以在程序中使用的两种解决方案

  1. 维护计数:

    for(int count = 0; count < array.length; count++) {
        System.out.println(array[count]);
    }
    

    或其他一些循环语句,例如

    int count = 0;
    while(count < array.length) {
        System.out.println(array[count]);
        count++;
    }
    
  2. 每个循环都使用一个更好的方法,在这种方法中,程序员无需担心数组中元素的数量。

    for(String str : array) {
        System.out.println(str);
    }
    

回答18:

根据您的代码:

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');
}

回答19:

数组中的每个项目都称为一个元素,每个元素都可以通过其数字索引进行访问。如上图所示,编号从0 开始。例如,第9个元素因此将在索引8处访问。

抛出IndexOutOfBoundsException表示某种索引(例如数组,字符串或向量)超出范围。

任何数组X均可从[0到(X.length-1)]访问

回答20:

我在这里看到所有答案,解释了如何使用数组以及如何避免索引超出范围异常。我个人不惜一切代价避免使用数组。我使用Collections类,这避免了必须完全处理数组索引的所有愚蠢行为。循环结构可与支持代码的集合完美配合,这些代码更易于编写,理解和维护。

回答21:

如果您使用数组的长度控制 for 循环的迭代,请始终记住,数组中第一项的索引为 0 。因此,数组中最后一个元素的索引比数组的长度小一个。

回答22:

ArrayIndexOutOfBoundsException名称本身说明,如果您尝试访问索引超出数组大小范围的值,则会发生这种异常。

对于您而言,您只需从for循环中删除等号即可。

for(int i = 0; i<name.length; i++)

更好的选择是迭代数组:

for(String i : name )
      System.out.println(i);

回答23:

此错误发生在运行循环超限时间。让我们考虑这样的简单示例,

class demo{
  public static void main(String a[]){

    int[] numberArray={4,8,2,3,89,5};

    int i;

    for(i=0;i<numberArray.length;i++){
        System.out.print(numberArray[i+1]+"  ");
    }
}

首先,我将一个数组初始化为'numberArray'。然后,使用for循环打印一些数组元素。当循环运行'i'时间时,打印(numberArray [i + 1]元素..(当i值为1时,打印numberArray [i + 1]元素。)..假设,当i =(numberArray。 length-2),则打印数组的最后一个元素。当'i'值到达(numberArray.length-1)时,没有打印值。.在这一点上,出现了'ArrayIndexOutOfBoundsException'。希望您能得到idea。谢谢你!

回答24:

您可以在函数样式中使用Optional来避免NullPointerExceptionArrayIndexOutOfBoundsException

String[] array = new String[]{"aaa", null, "ccc"};
for (int i = 0; i < 4; i++) {
    String result = Optional.ofNullable(array.length > i ? array[i] : null)
            .map(x -> x.toUpperCase()) //some operation here
            .orElse("NO_DATA");
    System.out.println(result);
}

输出:

AAA
NO_DATA
CCC
NO_DATA

回答25:

您不能迭代或存储比数组长度更多的数据。在这种情况下,您可以这样:

for (int i = 0; i <= name.length - 1; i++) {
    // ....
}

或者这个:

for (int i = 0; i < name.length; i++) {
    // ...
}
回到顶部