如何修复 java.lang.arrayindexoutofboundsexception: 0?

4

我是一个java的新手。请问有谁能帮我解决arrayindexoutofboundsexception错误。

public class Minesweeper { 
   public static void main(String[] args) { 

      int M = Integer.parseInt(args[0]);
      int N = Integer.parseInt(args[1]);
      double p = Double.parseDouble(args[2]);

      // game grid is [1..M][1..N], border is used to handle boundary cases
      boolean[][] bombs = new boolean[M+2][N+2];
      for (int i = 1; i <= M; i++)
         for (int j = 1; j <= N; j++)
            bombs[i][j] = (Math.random() < p);

      // print game
      for (int i = 1; i <= M; i++) {
         for (int j = 1; j <= N; j++)
            if (bombs[i][j]) System.out.print("* ");
            else             System.out.print(". ");
         System.out.println();
      }

      // sol[i][j] = # bombs adjacent to cell (i, j)
      int[][] sol = new int[M+2][N+2];
      for (int i = 1; i <= M; i++)
         for (int j = 1; j <= N; j++)
            // (ii, jj) indexes neighboring cells
            for (int ii = i - 1; ii <= i + 1; ii++)
               for (int jj = j - 1; jj <= j + 1; jj++)
                  if (bombs[ii][jj]) sol[i][j]++;

      // print solution
      System.out.println();
      for (int i = 1; i <= M; i++) {
         for (int j = 1; j <= N; j++)
            if (bombs[i][j]) System.out.print("* ");
            else             System.out.print(sol[i][j] + " ");
         System.out.println();
      }

   }
}

以下是异常信息:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at Minesweeper.main(Minesweeper.java:5) 

当没有这样的元素时,不使用索引0吗? - user180100
我得到了一个异常,异常信息为“Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0”,在Minesweeper.java的第5行,@Jens。 - user26
1
@user26,你的数组索引将从0开始,结束于M-1或N-1。 - Naveen Kulkarni
没有args [0] - 这是您使用的唯一0索引!其他应该为基于0的,但由于在末尾分配了额外的空间,因此也可以工作。 - CharlieS
@user26 是时候接受答案并关闭问题了。 - SMA
4个回答

9

可能有两个问题,正如它所说的索引0(请参见相同情况的第一个案例):

  1. 您没有将参数传递给您的主类。

  2. 数组索引始终从0开始而不是1。因此,您可能需要更改:

    • 循环以0开始并检查i < M或N
    • 将数组索引作为i-1而不是i使用。

您收到ArrayIndexOutOfBoundException的原因是假设您的数组中有2个元素。它将如下所示:

a[0] = 1;
a[1] = 2;

当您使用 i = 1; i<=2 进行循环时,您正在访问以下内容:

a[1] - which is perfect
a[2] - which was not expected?

其他人都忘记了传递参数 :) - ADTC
我没有,这是我的答案 :) 我甚至放了Eclipse的屏幕截图,说明如何使用运行配置的命令行参数。 - Levent Divilioglu
在我的情况下,我没有传递参数,因为我在编辑调用我的主类的长bash命令时意外删除了一行续行符。:( - combinatorist

5

在访问元素之前,您需要检查数组args的长度。由于您需要访问数组中的第二个元素,因此长度应至少为3。您可以像下面这样进行检查:

if(args.length > 2) {
  //wrap all code here
}

我宁愿使用防御性短语句 if (args.length < 3),并在其中加入错误信息和 return;。在我看来,将整个方法体包装起来会导致过度缩进。 - Joffrey

4

解决方案 #1:

您已使用如下命令行参数:args[0]、args1和args[3],这意味着您的类需要 3 个参数才能正确运行。但是由于您没有提供参数,因此出现了以下问题:

//      int M = Integer.parseInt(args[0]);
//      int N = Integer.parseInt(args[1]);
//      double p = Double.parseDouble(args[2]);

        int M = 2;
        int N = 3;
        double p = 3.99;

那么你的代码输出将是:
* * * 
* * * 

* * * 
* * * 

你的代码需要三个参数,我上面所做的只是使用赋值给这些参数,而不是使用args[]数组的值。

(解决方案 #2)

不必更改你的代码,你可以传递3个命令行参数,分别代表int M、N和double p。在eclipse中实现此操作:

  1. 右键单击你的类,选择运行为 -> 运行配置;

enter image description here

  1. 选择参数选项卡,并写入你的三个参数,它们之间留有空格;

enter image description here

现在,你将不会再次收到 "ArrayIndexOutOfBoundsException" 错误,使用值 2 4 0.9,输出将为:

* * . * 
* . * * 

* * 4 * 
* 4 * * 

(解释)

你的代码有两个问题:

  1. 你遇到了ArrayIndexOutOfBoundsException异常,这意味着你的代码试图访问一个超过索引的数组值。

  2. 你正在使用命令行参数,但是没有输入任何参数作为参数。 你的主要方法需要3个参数才能正确运行,但如果没有参数,args [0]args [1]args [2]表示有一个名为args [] 的数组,并且你正在尝试访问args []数组的第0、1和2个元素。 但是,如果不提供命令行参数,则尝试访问空值,从而得到以下错误信息;

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at com.stack1.Minesweeper.main(Minesweeper.java:8)

为了使其更清晰,首先我将解释什么是ArrayIndexOutOfBoundsException;

ArrayIndexOutOfBoundsException错误会在代码中的语句试图访问大于数组长度的数组索引时发生。 让我解释一下这个问题;

假设你有两辆车。 你的第一辆车的颜色是红色,你的第二辆车的颜色是蓝色。 如果我问你“你的第二辆车的颜色是什么”,你会回答“蓝色”。 但是如果我问“你的第五辆车的颜色是什么?” 你将回答“我没有第五辆车”。

ArrayIndexOutOfBoundsException”错误也是一样的, 在这种情况下,你只是返回一个“ArrayIndexOutOfBoundsException”错误,因为索引5大于汽车索引的最大计数,即汽车数组的长度。

String car[] = new String[2];

car[0] = "blue";
car[1] = "red";

为了更好地理解,让我们运行下面的代码:
public class CarColorExample
{

    public static void main(String[] args)
    {
        String[] carArray = new String[2];

        carArray[0] = "blue";
        carArray[1] = "red";

        System.out.println("1st car color value: " + carArray[0]);
        System.out.println("2nd car color value: " + carArray[1]);
        System.out.println("3rd car color value: " + carArray[2]);
    }

}

如果您尝试运行以上代码,将会得到以下异常;
1st car color value: blue
2nd car color value: red

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
    at com.stack1.CarColorExample.main(CarColorExample.java:15)

这里有一个语句 "java.lang.ArrayIndexOutOfBoundsException: 2",它实际上指向了超出索引范围的位置,并告诉你carArray没有第二个索引。

index: 0 --> "blue"
index: 1 --> "red"
index: 2 --> ????

作为关于 ArrayIndexOutOfBoundsException 错误的第二个例子,只需查看下面的代码并运行它;
    public static void main(String[] args)
    {
        int[] intArray = new int[3];

        intArray[0] = 25;
        intArray[1] = 36;
        intArray[2] = 99;

        //Will work with no error
        for(int i = 0; i < intArray.length; i++)
            System.out.println("index[" + i + "], value:" + intArray[i]);

        //      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
        //          at com.stack1.ErrorExample2.main(ErrorExample2.java:18)
        //
        //      "ArrayIndexOutOfBoundsException" error will occur for index: 3
        //      The length of the array is 2
        //      index: 0 --> 25
        //      index: 1 --> 36
        //      index: 2 --> 99
        //      There is no third index, That's all
        for(int i = 0; i < intArray.length + 1; i++)
            System.out.println("index[" + i + "], value:" + intArray[i]);
    }

}

我这里也有同样的问题,索引号为“3”,超出了数组的最大索引值,该值恰好存储在“intArray.length”中。


3

您需要检查是否有两个参数,可以使用以下代码:

if(args.length > 2)

此外,我认为更好的做法是改变这样的行:

。涉及IT技术相关内容。
for (int i = 1; i <= M; i++) {
 for (int j = 1; j <= N; j++)

转换为:

for (int i = 0; i <M; i++) {
 for (int j = 0; j < N; j++)

2
关于 for 循环,代码会过度分配内存:new boolean[M+2][N+2];,因此虽然不良实践,但在这种情况下并不是错误。 - Ken Y-N

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接