【问题标题】:2D Arrays and Null Pointer Exceptions (Java)二维数组和空指针异常 (Java)
【发布时间】:2012-02-05 02:56:49
【问题描述】:

我真的不知道是什么导致了这个问题,但是我的程序,应该是康威的生命游戏,在 2 代后崩溃,似乎不管我做什么,我已经尝试了几天来找到错误。

我已将原因缩小到几个可能的领域 - 或者至少,我认为我有。

short numNeighbors(int x, int y) {
    short numNeighbors; 
    numNeighbors = 0;
    if(x > 0 && y > 0 && matrix[x][y] != null){
        if (matrix[x+1][y] == true) numNeighbors++;
        if (matrix[x][y+1] == true) numNeighbors++;
        if (matrix[x+1][y+1] == true) numNeighbors++;
        if (matrix[x][y-1] == true) numNeighbors++;
        if (matrix[x-1][y] == true) numNeighbors++;
        if (matrix[x+1][y-1] == true) numNeighbors++;
        if (matrix[x-1][y+1] == true) numNeighbors++;
        if (matrix[x-1][y-1] == true) numNeighbors++;
    }
    return numNeighbors;
}
//returns the number of neighbours that a coordinate has

我假设上面的这一部分检查了我的二维数组的边界之外,但这应该是不可能的,因为我采取了预防措施来确保不会发生这种情况。即便如此,这也是一种可能的原因。

void nextGen(){
    Boolean[][] newMatrix = new Boolean[rows()][cols()];

    for (int i = 1; i < cols()-1; i++){
        for (int j = 1; j < rows()-1; j++){
        //avoiding null pointer errors
            if (matrix[j][i] == null) matrix[j][i] = false;
            //if a cell has 3 neighbours, become or stay true
            if (numNeighbors(j, i) == 3) newMatrix[j][i] = true;
            //if it doesn't have 3 neighbours, become or stay false
            else newMatrix[j][i] = false;
        }
    }

    matrix = newMatrix;
}
//makes matrix represent the next generation

这是我对错误原因的下一个猜测,但我真的无法确定会出现什么问题。

    for (int j = 0; j < numGenerations; j++){
        JOptionPane.showMessageDialog(null,"generation " + (j+1) + ":\n\n" + myGrid.showGrid());
        myGrid.nextGen();
    }

我只发布上面的内容,因为它调用了它上面的块,我不想排除任何东西。

我真的不知道还有什么问题,但以防万一有人想查看我项目的完整源代码,我已将其发布到on pastebin

【问题讨论】:

  • 堆栈跟踪中出现 NullPointerException 的行号是多少?那将是一个很好的起点。你试过调试它吗?在发生 NullPointerException 的行之前放置几个断点并检查数组值。
  • 您能发布堆栈跟踪信息吗?

标签: java nullpointerexception multidimensional-array conways-game-of-life


【解决方案1】:

我会在检查您的整个项目时发布另一个答案。

void nextGen(){
    Boolean[][] newMatrix = new Boolean[rows()][cols()];

您所做的是创建一个布尔对象数组,而不是布尔基元。

  • 布尔原语默认为 false
  • 布尔对象默认为 null

Java 有一种叫做自动装箱的东西,它可能会很棘手并隐藏这种“微小”的差异,实际上就像这里看到的那样,它们真的很重要,

【讨论】:

    【解决方案2】:

    实际上,所有块都应该用大括号括起来。如果你花时间这样做,你会多次拯救你的尾巴。例如,

    if (matrix[j][i] == null) {
       newMatrix[j][i] = false;
    }
    

    编辑 2
    你的大 if 块会有边界问题。为什么不简单地使用嵌套的 for 循环:

    short numNeighbors(int x, int y) {
      short numNeighbors; 
      numNeighbors = 0;
    
      int xMin = Math.max(x - 1, 0);
      int xMax = Math.min(x + 1, MAX_X - 1); // MAX_X is a constant, number of columns
      int yMin = Math.max(y - 1, 0);
      int yMax = Math.min(y + 1, MAX_Y - 1); // ditto, number of rows
    
      for (int i = xMin; i <= xMax; i++) {
         for (int j = yMin; j <= yMax; j++) {
            if (i != x && j != y) {
               if (matrix[i][j]) {
                  numNeighbors++;
               }
            }
         }
      }
    
      return numNeighbors;
    }
    

    正如在其他地方和我的评论中提到的,数组应该初始化为非空值,因此不需要进行空检查。

    【讨论】:

    • 逻辑有问题,但我不会生成 NPE。
    • 我这样做是为了检查矩阵 [] [] 中可能的空值。我对我的代码进行了类似的检查,但它们似乎没有帮助。我也尝试更改它,并没有透露额外的信息。两代后我仍然遇到同样的错误,同样的崩溃。
    • 我的评论是针对 Hovercraft Full Of Eels 预编辑答案
    • @Megafonzie:数组中的所有项目都应该是非空的,所以你甚至不应该做这个检查。
    • 关于边界问题,我已经考虑过了。我在矩阵的一部分周围留下了一堵坐标墙,我只需要让它比它需要的宽和高 2 倍,并且只在中间做一些事情。不过,您的方式更有效,我仍然感谢您的帮助!
    【解决方案3】:

    在 nextGen 中你会这样做:

     //avoiding null pointer errors
     if (matrix[j][i] == null) matrix[j][i] = false;
    

    numNeighbors() 中的所有 if 执行相同操作

    short numNeighbors(int x, int y) {
        short numNeighbors; 
        numNeighbors = 0;
        if(x > 0 && y > 0 && matrix[x][y] != null){
            if (matrix[j][i] != null && matrix[x+1][y] == true) numNeighbors++;
            if (matrix[j][i] != null && matrix[x][y+1] == true) numNeighbors++;
            if (matrix[j][i] != null && [x+1][y+1] == true) numNeighbors++;
            if (matrix[j][i] != null && matrix[x][y-1] == true) numNeighbors++;
            if (matrix[j][i] != null && matrix[x-1][y] == true) numNeighbors++;
            if (matrix[j][i] != null && matrix[x+1][y-1] == true) numNeighbors++;
            if (matrix[j][i] != null && matrix[x-1][y+1] == true) numNeighbors++;
            if (matrix[j][i] != null && matrix[x-1][y-1] == true) numNeighbors++;
        }
        return numNeighbors;
    }
    

    或者甚至更好地将所有单元格预实例化为 false。

    //Run in constructor
    for(int i ..
       for(int j ..
          matrix[j][i] = false
    

    【讨论】:

    • 我喜欢关于预实例化所有单元格的最后一部分。 1+
    • 我刚试过这个,它有效,但它是用 newMatrix,而不是矩阵。为了安全起见,我让矩阵的构造函数将其设为假,但我认为布尔值在 Java 中默认为假,但显然它们以 null 开头。我仍然不知道为什么它会持续两代人。
    猜你喜欢
    • 2011-02-07
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多