2013-04-05 3 views
4

Я уже провел исследование по этому вопросу, а также попытался выяснить это сам, но не повезло. Поэтому я решил спросить об этом.NullPointerException при вызове getter

Основная информация:

Есть два класса. FBClient и State. В FBClient у меня есть статическая переменная этого типа, fbc, экземпляр StateManager, который имеет только некоторые методы работы с State, некоторые константы и два геттера. В State, я пытаюсь инициализировать BufferedImage.

public class FBClient 
{ 
    //Static 
    public static FBClient fbc; 

    //In init method 
    private StateManager stateManager; 

    //Constants 
    private final int INIT_FRAME_WIDTH = 320, INIT_FRAME_HEIGHT = (INIT_FRAME_WIDTH/4) * 3, SCALE = 3, FRAME_WIDTH = INIT_FRAME_WIDTH * SCALE, FRAME_HEIGHT = INIT_FRAME_HEIGHT * SCALE; 

    public static void main(String[] args) 
    { 
     try 
     { 
      //First call in exception chain: 
      fbc = new FBClient(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      System.exit(1); 
     } 
    } 

    private FBClient() 
     throws IOException 
    { 
     //Second call in exception chain: 
     init(); 
    } 

    private void init() 
     throws IOException 
    { 
     stateManager = new StateManager(); 
     //Third call in exception chain: 
     stateManager.addState(new MainMenu((byte) 0, "Main Menu")); //MainMenu is the subclass of State, and the constructor just calls "super(0, "Main Menu")" 
    } 

    public int getFRAME_HEIGHT() 
    { 
     return FRAME_HEIGHT; 
    } 

    public int getFRAME_WIDTH() 
    { 
     return FRAME_WIDTH; 
    } 
} 

public abstract class State 
{ 
    protected final byte ID; 
    protected final String NAME; 
    protected final BufferedImage SCREEN; 
    protected final Graphics2D GRAPHICS; 

    public State(byte id, String name) 
    { 
     this.ID = id; 
     this.NAME = name; 
     //Exception cause: 
     this.SCREEN = new BufferedImage(FBClient.fbc.getFRAME_WIDTH(), FBClient.fbc.getFRAME_HEIGHT(), BufferedImage.TYPE_INT_RGB); 
     this.GRAPHICS = SCREEN.createGraphics(); 
    } 
} 

Подробнее:

Если я ставлю литералов при инициализации BufferedImage это работает.

Если я инициализирую две переменные в классе State, назначая им литералы и помещая эти переменные в инициализацию, он работает.

Если вместо присвоения литералов этим переменным я назначаю их FBClient.fbc.getFRAME_WIDTH() и FBClient.fbc.getFRAME_HEIGHT(), он выдает NullPointerException.

Если бы я сделать System.out.println(getFRAME_WIDTH + " : " + getFRAME_HEIGHT) в FBClient класс, он печатает нормально, но если я делаю это в State классе (и, конечно, добавив FBClient.fbc. перед ним), он бросает NullPointerException.

Если я FRAME_WIDTH и FRAME_HEIGHT константы public, и я пытаюсь получить доступ к ним из State класса, делая FBClient.fbc.FRAME_WIDTH и FRAME_HEIGHT, он бросает NullPointerException.

Если я попытаюсь получить доступ к константам из класса FBClient непосредственно, вместо геттеров он по-прежнему печатается правильно.

Наконец

Спасибо за ваше время, и если вам нужно больше информации для работы, спросите меня в комментариях, и я приведу его. Кроме того, я приношу свои извинения, если вопрос не построен хорошо/не объясняется хорошо. Если это так, скажите мне, как я могу улучшить его. Кроме того, я прошу прощения, если бы этот вопрос задавали и отвечали уже однажды, я, возможно, пропустил его, но, как я уже сказал, я сделал свое исследование.

Изменить # 1

Комментарий предложил мне распечатать значение fbc, чтобы увидеть, если это нуль. Итак, я добавил эту строку кода в конструктор State: if(FBClient.fbc != null) System.out.println("Not null"); else System.out.println("Null"); И, как подозревалось, он распечатал нуль. Почему это? Я четко инициализируется переменная в методе main ...

+0

Можете ли вы напечатать значение для «FBClient.fbc»? Я подозреваю, что его нет. – user1697575

+0

Да, я сделаю это прямо сейчас и сделаю редактирование, показывающее результат. –

ответ

1

Причина, по которой возникает проблема, заключается в том, что вы пытаетесь ссылаться на FBClient.fbc в своем вызове конструктора, и объект не завершил свою собственную конструкцию. Не сразу очевидно, что вы это делаете, но если вы следуете коду внутри конструктора, вы вызываете init(), который в конечном итоге вызывает конструктор состояния, который, в свою очередь, пытается использовать FBClient.fbc.getFRAME_WIDTH().

Я предлагаю вам не называть Init() в конструкторе FBClient и изменить свой основной код метода для:

public static void main(String[] args) 
    { 
     try 
     { 
      //First call in exception chain: 
      fbc = new FBClient(); 
      fbc.init(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      System.exit(1); 
     } 

    } 

Надеется, что это помогает.

2

Вы имеете в виду FBClient.fbc перед тем он назначен (на самом деле в конструкторе, так как FBC получить назначенный после того, как конструктор завершил работу). Чтобы исправить это, добавьте static к окончательным значениям, сделайте геттер статическим и получите его с помощью FBClient.getFRAME_HEIGHT().Вам не нужны нестатические конечные переменные.

+0

Я постараюсь сделать это. –

+1

Вот и все! спасибо –

Смежные вопросы