【问题标题】:ExceptionInInitializerError that I can't understand我无法理解的 ExceptionInInitializerError
【发布时间】:2013-02-02 08:07:47
【问题描述】:

这编译得很好:

static final Screen screen = Screen.getInstance();
static final InputListener listener = InputListener.getInstance();

static
{

    screen.addListener(listener);
    screen.setCurrentState(new MainMenu());
    screen.setVisible(true);
}

private GameManager(){
    mobs = new ArrayList<Mobile>();
    player = new Player(100, 100);      
    mobs.add(player);   
}

这不是:

static final Screen screen = Screen.getInstance();
static final InputListener listener = InputListener.getInstance();

private GameManager(){
    mobs = new ArrayList<Mobile>();
    player = new Player(100, 100);      
    mobs.add(player);   
    
    screen.addListener(listener);
    screen.setCurrentState(new MainMenu());
    screen.setVisible(true);
}

抛出:线程“main”中的异常 java.lang.ExceptionInInitializerError 说:

Caused by: java.lang.NullPointerException
at main.pack.minerdude.GameManager.<init>(GameManager.java:42)
at main.pack.minerdude.GameManager.<clinit>(GameManager.java:10)
... 1 more

第 10 行是:

private static final GameManager manager = new GameManager();

第 42 行指的是“退货经理”:

public static GameManager getInstance(){
    return manager;
}

如果静态块是在创建生物并添加玩家之后生成的,为什么会有这样的行为?

编辑

所以,这是我执行这段代码并得到以下输出后的结论:

GameManager constructor
Screen constructor
Screen getInstance
static of GameManager
GameManager GetInstance
  1. 有些类想要一个 GameManager 对象,所以要返回它,必须先创建它。

  2. GameManager 有一个声明为静态的 Screen 对象,并且具有与第一步相同的要求。

  3. 屏幕获取已创建,因此 GameManager 已初始化其静态对象并继续初始化以下静态对象。

  4. 现在 GameManager 已完全初始化,它会将自身返回给第一个调用者。

人们会假设当 GameManager getInstnace 被调用时,在调用它的构造函数之前,它会首先初始化它的所有静态,但它似乎不是这样工作的,因为构造函数在它的任何静态之前被调用。如果我直接创建一个新的 GameManager - 不使用 getInstance() - 然后将保留顺序:静态、变量、构造函数然后返回。

【问题讨论】:

  • at ..GameManager.java:42 虽然 42 可能是生命、宇宙和一切的意义,但该来源不包含 42 行。为了尽快获得更好的帮助,请发帖SSCCE
  • 我只发布了冲突的代码。我认为我在初始化它们之前尝试使用一些变量。我认为当你创建一个对象时,实例/类变量在构造函数之前首先被初始化。显然我错了,因为如果我在构造函数中初始化 statis,然后再赋予它们任何值,那么代码编译得很好。
  • 考虑阅读this question,它可能对你有所帮助。
  • 两者都 compile 很好,与您的描述相反。只是 执行 时的失败之一。
  • 鉴于堆栈跟踪,我怀疑第 42 行真的是 getInstance() 方法。我希望它在构造函数中。

标签: java exception static initialization


【解决方案1】:

您的问题是您在构造函数中使用静态对象,这取决于您的构造函数。

你的程序流程是:

1. static final Screen screen = Screen.getInstance();
2. public static GameManager getInstance(){ return manager;}
3. private static final GameManager manager = new GameManager();
4. private GameManager(){
    //......
    screen.addListener(listener);
    //but screen is still null !!! NullPointerException !!!
}

【讨论】:

  • 有些东西我不明白:我的 main 方法创建了一个名为“Start”的对象 --> 它创建了 GameManager getInstance(); --> 然后其余的被执行。我认为创建了 GameManager,然后是类/实例变量,然后调用构造函数。
  • 不,首先初始化类变量。见docs.oracle.com/javase/tutorial/java/javaOO/initial.html
  • 我在整个代码中添加了一些测试代码,这就是我得到的:“GameManager 构造函数 -> 屏幕构造函数 -> 屏幕 getInstance -> GameManager 的静态 -> GameManager GetInstance”。看起来它首先创建了一个新的 GameManager 对象,然后创建了一个 Screen 对象,然后返回屏幕,然后初始化 gameManager 的静态,然后返回 GameManager 对象。我想我现在理解了这个命令,但是一团糟!
猜你喜欢
  • 2011-08-31
  • 2017-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 2016-08-27
  • 1970-01-01
  • 2017-07-13
相关资源
最近更新 更多