0

我一直在尝试在实现特殊序列化(甚至序列化瞬态对象)时弄清楚流程,但我无法理解流程:

public class object1 implements Serializable {

int i = 2032423;
String str = "dssadsadsdfsfsdfczxc";
StringBuilder sb = new StringBuilder();
transient testobject ob1 = new testobject();
String str2;
testobject ob2;
String sooo =new String("jbdskdbshxcbc");

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


    try {

        FileOutputStream fos = new FileOutputStream(new File(
                "serialTst.txt"));
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        object1 obj1 = new object1();
        obj1.ob1.str = "this guy is referred";
        oos.writeObject(obj1);
        oos.flush();
        oos.close();
        fos.close();

        FileInputStream fis = new FileInputStream("serialTst.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        object1 obb=(object1)ois.readObject();
        System.out.println(obb.str2);

        ois.close();
        fis.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

private void readObject(ObjectInputStream Aois)
        throws ClassNotFoundException, IOException {
    Aois.defaultReadObject();
    str2 = (String) Aois.readObject();  

    System.out.println(ob1.str);
    System.out.println(sooo);    // Why Null here??
}

private void writeObject(ObjectOutputStream Aoos) throws IOException {

    Aoos.defaultWriteObject();
    Aoos.writeObject(ob1.str);
}

}

** 为什么 String sooo 为 null,即使打印正常 (String sooo="something") ????**

如果没有创建 object1 类的实例,那么 readObject 和 writeObject 是如何执行的?

4

2 回答 2

1

ob1未序列化,因为它被标记为transient. 此外,在反序列化对象时,Java 不会执行,也不会执行类的构造函数,也不会为字段设置默认值,而是会transient使用 Java 默认值填充字段,即int0Objectnull,因此您的ob1字段值将是null.

修复方法中的代码,您应该在使用之前readObject初始化该字段:ob1

private void readObject(ObjectInputStream Aois)
    throws ClassNotFoundException, IOException {
    Aois.defaultReadObject();
    str2 = (String) Aois.readObject();  //this is totally ok
    ob1 = new testobject();
    ob1.str = (String) Aois.readObject(); //this should work
    System.out.println(ob1.str);
}
于 2013-06-17T20:21:56.990 回答
0

所以我想问的是为什么会有NullPointerException,为什么ob1没有初始化?

反序列化既不调用constructor也不调用instance initializer给定的Serializable实现类。transient这意味着,声明为并因此未序列化的类的成员变量在default value通过反序列化从字节流中创建对象时被初始化。在你的情况下

transient testobject ob1 = new testobject();

期间不会执行deserialization。但是,由于对象正在被创建,因此JLS12.5必须将字段初始化为默认值。在反序列化时,可序列化类的所有字段(未标记为瞬态和静态object1) 都从流中恢复,并且transient变量(ob1)初始化为默认值null。这就是为什么下面一行:

System.out.println(ob1.str);

在你的readResolve方法内是NullPointerException因为ob1.str.

那么这些方法(readObject、writeObject)是如何开始执行的

readObjectwriteObject方法由JVM自动调用来分别写入和读取对象。

为什么 String sooo 即使打印正常 (String sooo="something") 也为空????

不,除非您在序列化String sooo之前完成,否则不能为空。null

于 2013-06-17T21:07:32.450 回答