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

时间:2013-08-09 00:43:39

标签: java pointers serialization stream 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();
    }

}

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

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

我猜是同样的事情。它也没用。我们的想法是让更多的类(Place除外)扩展Entry,允许使用Entry.serialize()方法对它们进行序列化。

2 个答案:

答案 0 :(得分:3)

String name; // Set by the subclass.

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

name课程中删除Place的声明。

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

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界面。请记住,您正在序列化它的实例。

答案 1 :(得分:1)

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

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