尝试将对象实例写入ObjectOutputStream时出现NullPointerException



我得到

Exception in thread "main" java.lang.NullPointerException
    at java.io.FileOutputStream.<init>(FileOutputStream.java:201)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:99)
    at lib.Entry.serialize(Entry.java:17)
    at main.Main.main(Main.java:8)

其中Entry.java:17stream.writeObject(this);(见下文)

Entry.java

package lib;
import java.io.*;
public class Entry { // Superclass.
    String filename; // Set below.
    String name; // Set by the subclass.
    public void main() {
        this.filename = this.name + ".ser";
        serialize();
    }
    public void serialize() {           
        try {
            FileOutputStream file = new FileOutputStream(this.filename);
            ObjectOutputStream stream = new ObjectOutputStream(file);
            stream.writeObject(this);
            stream.close();
            file.close();
            System.out.println("Serialized.");
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

Place.java

package lib;
public class Place extends lib.Entry { // A subclass.
    public String name;
    public Place(String name) {
        this.name = name;
    }
}

Main.java

package main;
import lib.Place;
public abstract class Main {
    public static void main(String[] args) {
        Place room = new Place("room");
        room.serialize();
    }
}

为什么我在使用this时会得到NullPointerException?我正在尝试将当前对象实例写入ObjectOutputStream。我是Java新手,不知道如何继续。在Python中,我会使用类似stream.writeObject(self)的东西,所以按照同样的思路,我在Java中使用了this。我试过使用stream.writeObject(Object this);,但没有用。我也试过

Object p = this;
stream.writeObject(p);

我想也是一样。它也不起作用。这个想法是让更多的类(而不是Place)扩展Entry,允许使用Entry.serialize()方法对它们进行序列化。

String name; // Set by the subclass.

这就是问题所在。由于您已经在子类中重新定义了name字段,因此它将不再使用this.name设置超类中的字段。Place类中的name字段遮蔽了Entry类中声明的字段。

Place类中删除name的声明。

然后用参数化构造函数替换Entry类中的main()方法。我不知道你为什么一开始就有它。你甚至都不叫它。

public Entry(String name) {
    this.name = name;
    this.filename = this.name + ".ser";
    // Don't call it here. Your object hasn't been fully constructed yet.
    // serialize();  
}

然后从Place构造函数调用超类构造函数,而不是直接设置字段:

public Place(String name) {
    super(name);
}

最后,制作Place类来实现Serializable接口。记住,您正在序列化它的实例。

没有调用Entry#main(),因为Main#main()现在是您的main()方法。您需要添加一个构造函数,将Entry类中的文件名初始化为

   public Entry() {
        this.filename = this.name + ".ser";
    }

相关内容

  • 没有找到相关文章