GuessingGame3构造方法中Null Pointer Exception问题求助
解决GuessingGame3中的Null Pointer Exception问题
嘿,我一眼就看到了几个导致你遇到Null Pointer Exception(NPE)的关键问题,咱们一步步来拆解和修复:
核心问题1:错误的构造方法定义
Java的构造方法没有返回类型,而且必须和类名完全一致。你写的:
public void GuessingGame3() { ... }
这不是构造方法,只是一个普通的方法!当你在main里执行GuessingGame3 game = new GuessingGame3();时,调用的是Java默认的无参构造方法(什么都不做),而不是你写的这个方法。之后你调用game.GuessingGame3()进入这个普通方法时,里面的game是类的成员变量public GuessingGame3 game;——这个变量根本没被初始化,一直是null,所以访问game.max自然会抛出NPE。
核心问题2:冗余且未初始化的类成员变量game
你的GuessingGame3类里自己持有了一个GuessingGame3 game成员变量,但完全没有必要。你应该直接访问当前实例的成员变量,而不是通过一个未初始化的引用。
其他次要问题
currentGuess和previousGuess被定义为static,但每个游戏实例应该有自己的猜测记录,static会导致多个实例共享这些值,逻辑错误。newGame方法里生成的answer是局部变量,没有赋值给类的成员变量this.answer,导致后续判断猜测对错时用的是默认值0。- 多处逻辑中直接访问成员变量时,没有明确区分局部变量和成员变量(比如
differential的局部变量和成员变量)。
修正后的完整代码
package guessinggame3; import java.util.Random; import java.util.Scanner; public class GuessingGame3 { public int max; public int answer; public int maxGuessesAllowed; public int numGuessTaken; public int currentGuess; // 去掉static,每个实例独立持有 public int previousGuess; // 去掉static public boolean gameOver; public int differential; // 正确的构造方法:无返回类型,和类名完全一致 public GuessingGame3() { Scanner sc = new Scanner(System.in); System.out.println("Welcome to the Guessing Game."); System.out.println("Enter the maximum number:"); this.max = sc.nextInt(); // 用this明确访问当前实例的成员变量 Random generator = new Random(); this.answer = generator.nextInt(this.max); // 赋值给类的answer成员变量 System.out.println("Enter the maximum number of guesses allowed:"); this.maxGuessesAllowed = sc.nextInt(); this.newGame(this.maxGuessesAllowed); } public static void main(String[] args) { // 直接new就会调用构造方法,不需要额外调用GuessingGame3()方法 new GuessingGame3(); } public void newGame(int guessesAllowed) { this.maxGuessesAllowed = guessesAllowed; Random generator = new Random(); this.answer = generator.nextInt(this.max); // 确保赋值给成员变量 System.out.println("The answer is:" + this.answer); this.gameOver = false; this.differential = this.max; this.numGuessTaken = 0; this.guess(); } public void guess() { Scanner sc = new Scanner(System.in); while (!this.gameOver) { System.out.println("Enter your guess:"); this.currentGuess = sc.nextInt(); this.numGuessTaken++; // 新增猜测次数统计 if (this.answer == this.currentGuess) { this.gameOver = true; System.out.println("Congratulations! You got it in " + this.numGuessTaken + " guesses!"); System.out.println("Would you like to play again? Enter Y for yes or N for no."); String again = sc.next().toUpperCase(); if (again.equals("Y")) { new GuessingGame3(); // 启动新游戏实例 } else if (again.equals("N")) { System.out.println("Goodbye."); break; } } else if (this.currentGuess > this.answer) { System.out.println("Too high"); } else if (this.currentGuess < this.answer) { System.out.println("Too low"); } if (this.currentGuess > this.max) { System.out.println("Your guess is beyond the max you set."); continue; } int currentDiff = Math.abs(this.answer - this.currentGuess); if (this.differential != 0) { if (currentDiff < this.differential) { System.out.println("Getting Warmer"); } else if (currentDiff > this.differential) { System.out.println("Getting Colder"); } } this.differential = currentDiff; // 新增:判断猜测次数是否超过限制 if (this.numGuessTaken >= this.maxGuessesAllowed) { this.gameOver = true; System.out.println("Game over! You've used all your guesses. The answer was: " + this.answer); System.out.println("Would you like to play again? Enter Y for yes or N for no."); String again = sc.next().toUpperCase(); if (again.equals("Y")) { new GuessingGame3(); } else { System.out.println("Goodbye."); } } } } }
关键修改点总结
- 把原来的
void GuessingGame3()改成真正的构造方法public GuessingGame3(),去掉返回类型,确保实例化时自动执行初始化逻辑。 - 删除了类中冗余的
GuessingGame3 game成员变量,所有成员变量访问都用this.xxx明确指向当前实例,避免空指针。 - 去掉了
currentGuess和previousGuess的static修饰符,保证每个游戏实例的猜测记录独立。 - 修复了
newGame方法中answer的赋值问题,确保类的成员变量被正确赋值。 - 补充了猜测次数超过限制的逻辑,让游戏流程更完整。
内容的提问来源于stack exchange,提问作者user3756741
相关产品推荐
相关产品推荐

