如何避免在我的代码中出现java.lang.NullPointerException错误?

huangapple go评论71阅读模式
英文:

How to avoid java.lang.NullPointerException in my Code?

问题

我已经在关于《生命游戏》实现的代码方面提出了一个问题。建议的解决方案解决了我的问题,但也产生了一个新问题。现在,如果我尝试调用 getCell() 方法,就会得到一个 java.lang.NullPointerException 异常。我该如何避免这个异常?

我的先前问题链接中包含了相应的代码以及我使用的解决方案代码:
链接地址

或者如果你只想要代码部分:

public class GameMap {
    private Cell[][] cellArray;

    private static Cell[][] buildCellArray(int width, int height){
        Cell[][] cellArray = new Cell[width][height];
        int i;
        int j;
        for(i = 0; i < width; i++) {
            for(j = 0; j < height; j++) {
                cellArray[i][j] = new Cell();
            }
        }
        return cellArray;
    }

    public GameMap(int sizeX, int sizeY) {
        buildCellArray(sizeX, sizeY);
    }

    public Cell getCell(int posX, int posY){
        return cellArray[posX][posY];
    }
}
英文:

I have asked a question about my code for a Game of Life Implementation. The suggested solution solved my problem but created a new one.<br/>
Now if I try to call the getCell() method I get a java.lang.NullPointerException.
How can I avoid this exception?<br/><br/>
Link to my previous question with the corresponding code and solution code that I used:
<https://stackoverflow.com/questions/63090328/how-can-i-access-the-cell-array-in-my-getcell-method-java/63094639#63094639>

Or if you just want the code:

public class GameMap {
	private Cell[][] cellArray;
	
	private static Cell[][] buildCellArray(int width, int height){
		Cell[][] cellArray = new Cell[width][height];
		int i;
		int j;
		for(i = 0; i &lt; width; i++) {
			for(j = 0; j &lt; height; j++) {
				cellArray[i][j] = new Cell();
			}
		}
		return cellArray;
	}
	
	public GameMap(int sizeX, int sizeY) {
		buildCellArray(sizeX, sizeY);
	}
	
	
	public Cell getCell(int posX, int posY){
		return cellArray[posX][posY];
	}
}

答案1

得分: 4

buildCellArray(sizeX, sizeY);

确实会构建一个新的数组并将其返回,但您没有将其赋值给需要赋值的字段。您只是丢弃了结果,而字段的值保持不变(null)。

您需要执行以下操作:

cellArray = buildCellArray(sizeX, sizeY);

您在静态方法中有一个与字段同名的局部变量,这有点令人困惑。但它们完全没有关联。尽量避免这种遮蔽。您可以将名称更改为例如:

private static Cell[][] buildCellArray(int width, int height){
Cell[][] newCellArray = new Cell[width][height];

英文:
buildCellArray(sizeX, sizeY);

That does indeed build a new array and returns it, but you are not assigning it to that field it needs to go to. You are just throwing away the result, and the field stays what it was (null).

You need to do

cellArray = buildCellArray(sizeX, sizeY);

It is a bit confusing that you have a local variable with the same name as the field in your static method. But they are completely unrelated. Try to avoid that kind of shadowing. You could change the name to for example

private static Cell[][] buildCellArray(int width, int height){
    Cell[][] newCellArray = new Cell[width][height];

答案2

得分: 1

就像Thilo提到的,你目前在方法中返回你创建的新的单元格数组,但是你从未在GameMap中赋值你的字段'cellArray'。相反地,你定义了一个同名的新变量cellArray,将所有关联的值存储在其中,然后返回它,但却没有使用它。

有很多种方法可以解决这个问题。你可以修改你的构造函数如下:

public GameMap(int sizeX, int sizeY) {
    this.cellArray = buildCellArray(sizeX, sizeY);
}

这会在你从buildCellArray返回后设置类的cellArray字段的值。

另一种方法是稍微修改你在buildCellArray方法中声明cellArray的方式,并且在方法定义中去掉static修饰符。不要再使用:

Cell[][] cellArray = new Cell[width][height];

你可以改为:

cellArray = new Cell[width][height];

这会起作用,因为在你的第一个示例中,你创建了一个全新的变量(同名,但位于不同的作用域)。这意味着在为它定义一切时你没有引用你的字段cellArray,而是只引用了你在buildCellArray内部创建的局部版本。然而在这个示例中,你将使用原始字段作为引用,而不是变量的局部版本。

英文:

Like Thilo mentioned, you currently return the new cell array that you create in the method, but you never assign your field 'cellArray' within GameMap. Instead, you define a new variable cellArray with the same name, store all of the associated values in there, return it, then don't use it.

There are quite a few ways to fix this. You could modify your constructor as such:

public GameMap(int sizeX, int sizeY) {
    this.cellArray = buildCellArray(sizeX, sizeY);
}

This would set the value of the class's cellArray field after you return from buildCellArray.

Another way would be to slightly change your declaration of cellArray in your buildCellArray method, and remove the static modifier on your method definition. Instead of saying:

Cell[][] cellArray = new Cell[width][height];

You could instead say:

cellArray = new Cell[width][height];

This would work because within your first example, you're creating a whole new variable (with the same name, but under a different scope). This means you don't reference your field cellArray when you define everything for it, but only reference the local version you created inside of buildCellArray. In this example though, you would be using the original field as your reference, instead of the local version of the variable.

huangapple
  • 本文由 发表于 2020年7月26日 09:32:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63095257.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定