简体   繁体   English

取消序列化保存的对象时发生NullPointerException吗?

[英]NullPointerException when de-serializing a saved object ?

I input instructions using command line arguments. 我使用命令行参数输入指令。 I pass the location of where the text file which contains info on how to run the class is present . 我通过了包含有关如何运行类的信息的文本文件所在的位置。 In one instance the program has to act like it has an error and it needs to shut down. 在一种情况下,程序必须像发生错误一样动作,并且需要关闭。 I am able to do this. 我能够做到这一点。 the object is also serlized in the end. 最后该对象也被serlized。 Now i have to use the same ser file to restart the program and start it from the same place as it last shut down using the restore class. 现在,我必须使用相同的ser文件来重新启动程序,并从与上次使用restore类关闭的位置相同的位置启动它。 For some odd reason i am getting a nullpinterException . 由于某些奇怪的原因,我得到了nullpinterException。 I have marked where i am getting that error. 我已标记出我在哪里得到该错误。

public static void main(String[] args) throws Exception {

    try {

        String option = args[0];
        String filename = args[1];


        if (!(option.equals("-f")) && !(option.equals("-d"))) {
            System.out.println("Invalid option");
            printUsage();
        }

        System.out.println(filename);
        GreenhouseControls gc = new GreenhouseControls();

        if (option.equals("-f")) {
            gc.addEvent(gc.new Restart(0, filename));
        try {
                        FileOutputStream fileOut = new FileOutputStream("/Users/Arsalan Khan/Google Drive/cosc/TME/src/dumpout.ser");
                        ObjectOutputStream out = new ObjectOutputStream(fileOut);
                        out.writeObject(gc);
                        out.close();
                    } catch (IOException i) {
                        i.printStackTrace();
                    }
        }
        gc.run();

        // serialization try catch


        // the instance where the error occored is also passed to
        if (option.equals("-d")) {

        // GreenhouseControls.main(GreenhouseControls.java:567) 
            Restore re = new Restore(filename);


        }

    }

    catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("Invalid number of parameters");
        printUsage();
        e.printStackTrace();
    }

}

public class Restore {
String fileNameNew;

public Restore(String fileName) {

    this.fileNameNew = fileName;

}

// print the state of the save to the console
{// deserilize dump.out
    try {
        // here at Restore.<init>(Restore.java:17)
        FileInputStream fileIn = new FileInputStream(fileNameNew); 
        ObjectInputStream in = new ObjectInputStream(fileIn);

        // it has to be cast to GreenhouseControls since everything saved in
        // a file is retrieved as an object
        GreenhouseControls readGreen = (GreenhouseControls) in.readObject();
        in.close();
        System.out.println(readGreen);
        // since we are trying to fix the error in gc we will pass its
        // instance and use fixable to fix it
        readGreen.getFixable((Integer) readGreen.errorCode);
    } catch (IOException | ClassNotFoundException i) {
        i.printStackTrace();
    }
}

// restart from where it left the program
// run fix window and power on to fix problems

;

} }

An exception at that point can only because fileNameNew is null . 此时的异常只能是因为fileNameNewnull And it won't be thrown there. 而且不会在那里。 It must be thrown in the constructor chain, or in some method that it calls. 它必须在构造函数链或它调用的某些方法中抛出。

The problem is happening before you attempt to deserialize anything, and is (actually) nothing to do with the deserializion process. 尝试对任何内容进行反序列化之前 ,问题就已经发生了,并且(实际上)与反序列化过程无关。

In fact, the reason that fileNameNew is null is that you are attempting to do stuff in an instance initializer block. 实际上, fileNameNewnull的原因是您正在尝试在实例初始化程序块中进行操作。 (Bad idea ...) That block gets executed before the Restore constructor body, and at that point, the fileNameNew field will still be in its default initialized state. (坏主意...)该块在Restore构造函数主体之前执行,并且此时, fileNameNew字段仍将处于其默认的初始化状态。

The solution is to put the code that is in the instance initializer block inside the constructor, so that it executes after this.fileNameNew = fileName; 解决方案是将实例初始化程序块中的代码放在构造函数中,以便在this.fileNameNew = fileName;之后执行this.fileNameNew = fileName;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM