Java Singleton NullPointerException - PullRequest
       17

Java Singleton NullPointerException

1 голос
/ 15 сентября 2011

Я строю свою первую игру на Java с нуля. Я решил, что класс GameWorld, который централизует основные операции в игре (обработка ввода и т. Д.), Лучше всего реализовывать как одиночный (с использованием enum). Соответствующий код для перечисления ниже.

public enum GameWorld {
    INSTANCE;
    private static InputController input = InputController.getInput();
    public EntityPlayer player = new EntityPlayer(10, 10, 5, 5);

    public static GameWorld getWorld() {
        return INSTANCE;
    }

    public InputController getInputController() {
        return input;
    }
}

Исключение происходит в конструкторе EntityPlayer. Код и трассировка стека приведены ниже.

public class EntityPlayer implements Entity, InputListener {
    private int xPos;
    private int yPos;
    private int width;
    private int height;

    // Velocity of object
    // Determines where it sets itself on update
    private int xVel;
    private int yVel;
    private GameWorld world;

    private InputController input;

    private boolean solid;

    public EntityPlayer(int x, int y, int width, int height) {
        xPos = x;
        yPos = y;
        this.width = width;
        this.height = height;
        solid = true;
        xVel = 0;
        yVel = 0;
        world = getWorld();
        input = world.getInputController();
        input.registerKeyListener(this);
    }

    @Override
    public Graphics draw(Graphics g) {
        g.setColor(Color.yellow);
        g.fillRect(xPos, yPos - height, width, height);
        return g;
    }

    @Override
    public void update() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getXPos() {
        return xPos;
    }

    @Override
    public int getYPos() {
        return yPos;
    }

    @Override
    public Rectangle getRect() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isSolid() {
        return solid;
    }

    @Override
    public void kill() {

    }

    @Override
    public GameWorld getWorld() {
        return GameWorld.getWorld();
    }

    @Override
    public void sendKeyPress(KeyEvent ke) {
        System.out.println(ke.getKeyChar());
    }

    @Override
    public void sendMouseMove(MouseEvent me) {

    }

}

Трассировка стека:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.pvminecraft.gameworld.Main.<clinit>(Main.java:14)
Caused by: java.lang.NullPointerException
at com.pvminecraft.gameworld.entities.EntityPlayer.<init>(EntityPlayer.java:45)
at com.pvminecraft.gameworld.GameWorld.<init>(GameWorld.java:15)
at com.pvminecraft.gameworld.GameWorld.<clinit>(GameWorld.java:13)
... 1 more

В строке 14 Main.java я получил еще один экземпляр GameWorld для тестирования. Я не уверен, почему это вызывает исключение. Если я удалю ссылки на GameWorld в EntityPlayer, он исчезнет. Если вам нужен код для Main.java, сообщите мне в комментариях, и я опубликую его. Спасибо!

EDIT: Строка 45 в EntityPlayer имеет вид «input = world.getInputController ();» Я почти уверен, что мир нулевой, хотя понятия не имею, почему.

Ответы [ 2 ]

2 голосов
/ 15 сентября 2011

Вы поворачиваетесь кругами.

Вы хотите инициализировать переменную GameWorld.INSTANCE.Прежде чем вы сможете это сделать, вы должны инициализировать все поля класса GameWorld.После инициализации всего поля будет присвоена переменная INSTANCE.До того, как это произойдет, оно все еще имеет значение по умолчанию null.

. Во время инициализации поле player инициализируется.И в этой инициализации вы уже получаете доступ к полю INSTANCE.Итак, у вас круговая зависимость.

Вы действительно должны разъединить свои классы, чтобы они стали более независимыми друг от друга.

0 голосов
/ 15 сентября 2011

Я не видел никакой гарантии, что выражение

InputController.getInput()

вернет ненулевое значение.А так как ваш код очень удобен для отладки (по крайней мере, по одному исключению NullPointerException на строку), будет просто увидеть, какая переменная равна нулю.

Как я уже говорил, я подозреваю input.

...