Java 扫雷机程序中的NullPointerException
所以我是一名计算机科学专业的学生,也是一名初出茅庐的Java程序员。有人让我帮助他们完成一项任务,他们必须创建一个非常基本的扫雷程序。这个程序根本不使用悬挂地雷,但除此之外,它的功能与其他扫雷游戏相同 当我试图运行程序时,我遇到了NullPointerException。我已经研究过这可能意味着什么,现在知道这应该是一个NoObjectException或DereferenceException,但我仍然没有解决这个问题 调用Tile类的makeField方法时会出现此异常。另外,我真的在想正确的继承,静态与非静态,公共与私有,以及所有这些是如何相互关联的,如果这是一个完全没有意义的问题,我很抱歉 所以,我有一个主文件,一个Tile超类,和Tile类的两个子类-Bomb和Flat。Bomb是一块有炸弹的瓷砖,而Flat是任何不是炸弹的瓷砖Java 扫雷机程序中的NullPointerException,java,class,inheritance,nullpointerexception,Java,Class,Inheritance,Nullpointerexception,所以我是一名计算机科学专业的学生,也是一名初出茅庐的Java程序员。有人让我帮助他们完成一项任务,他们必须创建一个非常基本的扫雷程序。这个程序根本不使用悬挂地雷,但除此之外,它的功能与其他扫雷游戏相同 当我试图运行程序时,我遇到了NullPointerException。我已经研究过这可能意味着什么,现在知道这应该是一个NoObjectException或DereferenceException,但我仍然没有解决这个问题 调用Tile类的makeField方法时会出现此异常。另外,我真的在想正确
public class MineSweeperMain{
public static void main(String[] args)
{
Scanner kybd = new Scanner(System.in);
int dimension;
Tile[][] gameBoard;
System.out.print("Enter the dimension of the board you would like to play on:\t");
dimension = kybd.nextInt();
gameBoard = Tile.makeField(dimension);
Tile.printField(gameBoard, dimension);
}
}
//
//
//这里有很多问题,但要回答为什么会得到空指针的主要问题:
Board[i][randomInRow] = new Bomb();
在上面的代码中,您在每一行的电路板周围随机放置炸弹。请注意,这将仅为正方形的子集设置一个值
然后循环遍历每个方块并执行以下操作:
if(!Board[i][j].isBomb) Board[i][j] = new Flat();
问题是,如果正方形没有被指定为炸弹,它就没有被指定任何东西,所以它是空的。当你对空值的东西调用isBomb
时,你会得到一个空指针。此测试应改为检查板[i][j]==null
也就是说,您可能希望开始时比这个小。虽然就游戏而言,这是一个相对基本的概念,但我认为在深入研究类似的内容之前,您需要对java有更多的基本了解。我想我看到了问题所在。制作板时,将炸弹设置为一行中的随机元素。然后你检查所有的炸弹,看看那里有没有炸弹
if(!Board[i][j].isBomb) // What if board[i][j] is not set? Null Pointer Exception
Board[i][j] = new Flat();
这有用吗?我认为您的问题在
makeField
方法的第二个循环中
当您选中(!Board[i][j].isBomb)时,该特定值将为null,因为您尚未完全填充数组。第一个循环放置了几个随机炸弹,但其余的值为空
我建议你倒过来。首先循环检查所有内容,并使整个电路板在不检查任何内容的情况下变平
然后在第二个循环中,您只需用Bomb
s覆盖两个平面
s
另一个解决方案就是进行这个微小的修改并检查null:
if(null==Board[i][j]| |!Board[i][j].isBomb)
请注意,如果采用此解决方案,则必须首先执行空检查。这是因为一种叫做
我之所以推荐我的第一个切换循环的解决方案,是因为它消除了1个额外的比较,这不是什么大问题,但你永远不知道…当你声明多维数组时,你不会在数组中创建任何对象。你需要像这样的东西
for(int i = 0; i < dimensions; i++) {
for(int j = 0; j < dimensions; j++) {
Board[i][j] = new Tile();
}
}
for(int i=0;i
问题在于,您没有填充炸弹
阵列
您将需要以下内容:
for(int i = 0; i < dimensions; i++)
for(int j = 0; j < dimensions; j++){
Board[i][j] = new Tile(); // or something
if(!Board[i][j].isBomb()) // use an accessor
Board[i][j] = new Flat();
}
return Board;
}
for(int i=0;i
这里的问题是电路板未使用默认磁贴进行初始化
你有:
Tile[][] Board = new Tile[dimensions][dimensions];
然后你随机分配炸弹:
Board[i][randomInRow] = new Bomb();
不是炸弹的瓷砖仍然是空的。因此,调用此函数将导致NPE(NullPointerException):
要解决此问题,请将该行更改为:
if (!Board[i][j] == null)
因此,如果当前位置的电路板为空,那么它肯定没有初始化为炸弹。还有其他方法可以扭转代码来解决这个问题,但这是我想到的最简单的方法。NullPointerException在哪里?(哪个语句?)读取异常的堆栈跟踪。这不是毫无意义的垃圾。它告诉您异常发生在代码中的确切位置,以及引发异常时整个调用堆栈是什么。若你们不明白,在你们的问题中贴出来,告诉我们它指向哪一行代码。1)类应该以大写开头,变量名应该以小写开头。2)
System.out.println
是一个简单的NullPointerException的便捷调试工具,只需查看什么引用实际为null,然后从那里返回。NullPointerException这个名称并没有真正触及问题的核心,这一点您是绝对正确的。C#具有NullReferenceException,这是一个更好的名称,因为Java和C#等语言具有引用而不是指针(除非您正在编写/使用显式标记为不安全的C#代码)。有关区别的更多信息,请参见。这就是问题所在,但此解决方案将覆盖他刚才放置的所有炸弹。啊,非常感谢。我现在明白了。我将使用您的第一个建议。@JamesMontagne您是对的,没有看到数组是用两个维度声明的。当然,你可以按照我写的方法创建数组,这就是如何为每个子数组创建一个长度不同的多维数组(例如,创建一个三角形数组)。是的,我收回第二部分。还有,仅供参考,不是我的反对票。@JamesMontagne好吧,你的评论很有道理。谢谢
Tile[][] Board = new Tile[dimensions][dimensions];
Board[i][randomInRow] = new Bomb();
if (!Board[i][j].isBomb)
if (!Board[i][j] == null)