4

我已经对这个问题进行了研究,也试图自己弄清楚,但没有运气。所以我决定问问。

基本信息:

有两个班。FBClient, 和State. 在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()and FBClient.fbc.getFRAME_HEIGHT(),它会抛出一个NullPointerException.

如果我System.out.println(getFRAME_WIDTH + " : " + getFRAME_HEIGHT)FBClient课堂上做 a ,它会正确打印出来,但如果我在State课堂上做(当然FBClient.fbc.在它之前添加),它会抛出一个NullPointerException.

如果我制作FRAME_WIDTHFRAME_HEIGHT常量public,并且我尝试通过执行和从State 类中访问它们,它会抛出一个.FBClient.fbc.FRAME_WIDTHFRAME_HEIGHTNullPointerException

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

最后

感谢您抽出宝贵时间,如果您需要更多信息,请在评论中询问我,我会提供。另外,如果问题没有很好地构建/没有很好地解释,我深表歉意。如果是这种情况,请告诉我如何改进它。而且,如果这个问题已经被问过并回答过一次,我很抱歉,我可能错过了,但正如我所说,我做了我的研究。

编辑#1

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

4

3 回答 3

2

您指的是 FBClient.fbc在分配之前(实际上是在构造函数中,因为 fbc 在构造函数完成工作后被分配)。要修复它添加static到最终值,使 getter 静态并使用FBClient.getFRAME_HEIGHT(). 您不需要非静态最终变量。

于 2013-04-05T16:44:21.543 回答
1

您遇到问题的原因是因为您试图在其构造函数调用中引用 FBClient.fbc 并且该对象尚未完成自己的构造。您正在这样做并不是很明显,但是如果您按照构造函数中的代码调用 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);
        }

    }

希望这可以帮助。

于 2013-04-05T17:29:08.173 回答
0

我认为你FBClient.fbc是空的。

于 2013-04-05T16:45:42.853 回答