我已经对这个问题进行了研究,并且尝试自己解决这个问题,但是没有运气。所以我决定问这个。

基本信息:

有两节课。 FBClientState。在FBClient中,我有一个类型为它的静态变量fbc(一个StateManager实例),该实例只有一些可用于State的方法,一些常量和两个getter。在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_WIDTHFRAME_HEIGHT常量public,我尝试从State访问它们
通过执行FBClient.fbc.FRAME_WIDTHFRAME_HEIGHT类,它将引发NullPointerException

如果我尝试直接从FBClient类访问常量,而不是getters,它仍然可以正确打印。

最后

感谢您抽出宝贵的时间,如果需要更多信息,请在评论中问我,我会提供。另外,对于这个问题的解释不好/解释不好,我也表示歉意。如果是这样,请告诉我如何改善它。而且,如果这个问题已经被问到并回答过,我很抱歉,我可能错过了,但是正如我所说,我做了我的研究。

编辑#1

一条注释建议我打印出fbc值,以查看其是否为空。
所以我将这行代码添加到State构造函数中:if(FBClient.fbc != null) System.out.println("Not null"); else System.out.println("Null");并且,据怀疑,它打印出了null。这是为什么?我清楚地在main方法中初始化了变量...

最佳答案

您遇到问题的原因是因为您尝试在其构造函数调用中引用FBClient.fbc,并且该对象尚未完成其自身的构造。这样做并不是立即显而易见的,但是如果您遵循构造函数中的代码,则会调用init(),而init()最终将调用State构造函数,而该构造函数又会尝试使用FBClient.fbc.getFRAME_WIDTH()。

我建议您不要在FBClient构造函数中调用init()并将主要方法代码更改为:

    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);
        }

    }

希望这可以帮助。

09-15 21:14