Caused by: java.lang.NullPointerException

Main.java

package test;

public class Main {

    public static void main(String[] args) {
        GameModel.getInstance();
        System.out.println(GameModel.getInstance().objects);
    }
}

GameModel.java

package test;

import java.util.ArrayList;
import java.util.List;

public class GameModel {

    List<Tank> objects = new ArrayList<Tank>();
    private  static GameModel INSTANCE = new GameModel();

    private GameModel() {
       new Tank();
   }

    public static GameModel getInstance() {
        return INSTANCE;
    }

    public void add(Tank t) {

        this.objects.add(t);
    }
}

Tank.java

package test;

import java.awt.*;

public class Tank {

    public Tank() {
        GameModel.getInstance().add(this);

    }
}

运行Main.main() 报错:

/Library/Java/JavaVirtualMachines/jdk-12.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=52752:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/www/DesignPatterns/game_tank/out/production/game_tank test.Main
Exception in thread "main" java.lang.ExceptionInInitializerError
    at test.Main.main(Main.java:6)
Caused by: java.lang.NullPointerException
    at test.Tank.<init>(Tank.java:8)
    at test.GameModel.init(GameModel.java:20)
    at test.GameModel.<init>(GameModel.java:16)
    at test.GameModel.<clinit>(GameModel.java:9)
    ... 1 more

Process finished with exit code 1

报错分析:
GameModel.getInstance()
--》 return INSTANCE;
--》 private static GameModel INSTANCE = new GameModel();
--》
private GameModel() {
new Tank();
}
--》执行Tank的构造方法
--》 GameModel.getInstance().add(this);
--》 此时使用add()报错: 此时GameModel并未完成实例化操作、Tank的构造方法中拿不到一个GameModel实例、因此报空指针

解决方案:
将GameModel初始化逻辑移出构造方法、放置静态代码块、即先实例化成功--》new Tank() --> Tank此时可以拿到GameModel实例 --》 bug解决

GameModel.java
改动前:

public class GameModel {

    private GameModel() {
       new Tank();
   }

}

改动后:

public class GameModel {

    static {
        new Tank();
    }

    private GameModel() {}
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 废话不多说,自己进入今天的主题 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:...
    传奇内服号阅读 2,396评论 1 31
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,415评论 0 4
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,765评论 18 399
  • 51、类ExampleA继承Exception,类ExampleB继承ExampleA。 有如下代码片断: try...
    Nathan_Yang阅读 647评论 0 0
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 2,031评论 0 3