反序列化后,瞬态字段变为空?

时间:2016-01-01 09:55:32

标签: java serialization transient

我目前正在使用JAVA内置的序列化程序java.io.Serializable,并且似乎无法将其反序列化并将我的字段设置为默认值。我甚至尝试使用readObject来初始化字段,但它只是不起作用。

这是我的代码:

public abstract class BossQuest implements Quest, 
            Listenable { //Quest(interface) extends Serializable

private transient Status status = Status.IDLE; //This does not work

private String name;

public BossQuest(String name) {
    this.name = name;
    initialize();
}

//This also does not work
public BossQuest() {
    this.status = Status.IDLE;
}

//This was my hacky attempt to forcefully set default values (Does not work)
public void initialize() {
    status = Status.IDLE;
}

private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
    ois.defaultReadObject();
    initialize();
}

public Status getStatus() {
    System.out.print("Requesting status!");

    if (status == null) {
        System.out.print("Status is.. null..?"); 
    }

    System.out.print(status);

    return status;
}
}

在上面的代码中,Quest扩展了Serializable

我反序列化文件后,唯一的时间状态为null。它不能通过任何mutator设置为null。

1 个答案:

答案 0 :(得分:1)

只需使用readResolve()将状态初始化为IDLE。

这是一个完整的例子:

public class BossQuest implements Serializable {
    private String name;
    private transient int status = 42;

    public BossQuest(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    private Object readResolve() {
        this.status = 42;
        return this;
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        BossQuest in = new BossQuest("test");
        in.setStatus(987);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(in);
        oos.close();

        byte[] b = baos.toByteArray();

        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(b));
        BossQuest out = (BossQuest) ois.readObject();
        System.out.println(out.getName()); // prints test
        System.out.println(out.getStatus()); // prints 42
    }
}