为什么我的 TimerTask.cancel() returns 是 NPE? (JAVA)

Why does my TimerTask.cancel() returns an NPE ? (JAVA)

我正在编写作业,目前一切正常。我不打算 post 整个事情,而是要调用和引用基本的 classes。

基本上,我的问题是我有一个 GameTimer class 来在我的游戏中启动一个计时器:

public class GameTimer  {

    GameViewController gvc = GameFrame.gameViewController;
    public static boolean isRunning = false;

    public int seconds = 0;

    public Timer timer = null;
    public TimerTask task = null;

    public GameTimer () {
        timer = new Timer();
    }

    public void start() {
        task = new TimerTask() {
            @Override
            public void run() {
                gvc.updateTime(seconds);
                seconds++;
            }
        };
        timer.scheduleAtFixedRate(task, 1000, 1000);
        System.out.println("Task was started");
        isRunning = true;
    }

    public void stop() {
        task.cancel();
        timer.cancel();
        timer.purge();
        isRunning = false;
    }

    public void restart() {
        stop();
        start();
    }
}

基本上我有不同的模式来扩展 GameModel 并在我的 GameModel 中引用我的 GameTimer 实例 class :

public class GameModel {
    public GameTimer game_timer = new GameTimer();
    //... Rest of instances and classes
}

public class Mode1 extends GameModel {
    public Mode1() {
        if(!gamer_timer.isRunning)
            game_timer.start();
        else
            game_timer.restart();
    }
    //.....Rest of methods
}

public class Mode2 extends GameModel {
    public Mode2() {
        if(!gamer_timer.isRunning)
            game_timer.start();
        else
            game_timer.restart();
    }
    //.....Rest of methods
}

基本上,我的游戏是一个 GUI,我有一个下拉框,我可以从中 select 我的模式。我的游戏在运行时立即加载模式 1,但是当我选择模式 2 时,它 returns 在我的

上出现 NullPointerException
  task.cancel();

我在其他一些 post 上读到,您必须在计时器之前取消 TimerTask,但是我是否在任务取消之前放置了计时器取消 task.cancel
timer.cancel() 它仍然给我相同的 NullPointerException

这是错误:

  Exception in thread "AWT-EventQueue-0" Mode2
  java.lang.NullPointerException
       at GameTimer.stop(GameTimer.java:32) // task.cancel()
       at GameTimer.restart(GameTimer.java:39)
       at Mode2.<init>(Mode2.java:15)

你能帮我弄清楚为什么任务没有取消吗?

我没有逐行清楚地阅读您的解释,但是看到您的代码我可以说,

restart() 方法中,您首先调用 stop(),然后调用 start() 第二个

public void restart() {
        stop();
        start();
    }

在 start() 方法中,您正在像此处一样初始化 task 对象

 public void start() {
        task = new TimerTask()

但根据您的代码,这似乎是您代码的第二优先级,首先调用 stop(),但当时 task 未初始化。我建议你根据你的需要重新安排它,并在你觉得舒服的任何地方初始化 task,但请确保你在使用前进行了初始化。

为什么 isRunning 是静态的?

模式 1 将其设置为真。 Mode2 已创建,它 should 读为 false for isRunning 但它读为 true (class variable = only one used)所以而不是调用 start( ) 它会调用 restart( ) 并获取 NPE,因为它从未启动,因此无法停止。

感谢您的帮助。我找到了解决方案。正在初始化模式 1,因为我 运行 游戏

 new Mode1 ();

和模式2一样。当我在我的游戏中选择模式 2 时它会初始化。但是,因为我在我的程序中重新初始化相同的 gameModel,所以 isRunning 一开始总是错误的,因为在我的 GameModel 中,你看到我每次都创建一个新的 GameTimer 实例。所以基本上,定时器的状态永远不会设置为真。

我发现我的代码存在问题,但我还没有找到解决方案,所以我会在完成后立即 post 解决方案。感谢您的帮助