You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.");
                }
            }
        }
    }
}

关键修改点总结

  1. 把原来的void GuessingGame3()改成真正的构造方法public GuessingGame3(),去掉返回类型,确保实例化时自动执行初始化逻辑。
  2. 删除了类中冗余的GuessingGame3 game成员变量,所有成员变量访问都用this.xxx明确指向当前实例,避免空指针。
  3. 去掉了currentGuess和previousGuess的static修饰符,保证每个游戏实例的猜测记录独立。
  4. 修复了newGame方法中answer的赋值问题,确保类的成员变量被正确赋值。
  5. 补充了猜测次数超过限制的逻辑,让游戏流程更完整。

内容的提问来源于stack exchange,提问作者user3756741

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:42:48