对象的序列化(java)

时间:2013-06-28 08:39:47

标签: java serialization

我有以下代码:

import java.io.*;

public class TestSer {
    public static void main(String[] args) {
        SpecialSerial s = new SpecialSerial();
        try {
            ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("myFile"));
            os.writeObject(s); os.close();
            System.out.print(++s.z + " ");                         ...(1)
            ObjectInputStream is = new ObjectInputStream(new FileInputStream("myFile"));
            SpecialSerial s2 = (SpecialSerial)is.readObject();
            is.close();
            System.out.println(s2.y + " " + s2.z);
        } catch (Exception x) {
            System.out.println("exc");
        }
    }
}

class SpecialSerial implements Serializable {
    transient int y = 7;
    static int z = 9;
}

现在,当我运行代码时,输​​出为“10 0 10”。但为什么它是“10 0 10”而不是“10 0 0”?我的意思是当我反序列化对象时,y和z(是瞬态和静态resp)应该返回7和9,这是默认值(请在此时纠正我因为我认为对象在反序列化后得到的值是默认值)。语法“++ object.var”的含义是什么(参考(1))。它与“Object var ++”相同,即“++ s.z”与“s.z ++”相同吗?

7 个答案:

答案 0 :(得分:2)

由于SpecialSerial.z被声明为z,因此只有一个内存位置在内存中保存static的值。此值优先于从文件反序列化的值。

添加:

private void writeObject(ObjectOutputStream oos) throws IOException {

    oos.defaultWriteObject();
    oos.writeInt(z);
    System.out.println("session serialized");
}

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {

    ois.defaultReadObject();
    z = ois.readInt();
}

会使用从文件中反序列化的静态值覆盖z的静态值。

我不会建议这种技术,因为它可能导致难以解决的问题。

答案 1 :(得分:1)

  

现在,当我运行代码时,输​​出为“10 0 10”。但为什么它是“10 0 10”而不是“10 0 0”?

当通过反序列化获得对象时,瞬态变量将填充默认值。但它共享相同的static variable(或类变量),它存在于给定类的JVM中。这就是为什么s.z的值显示为10,这是当前正在运行的应用程序中z的现有值。

  

是“++ s.z”和“s.z ++”相同吗?

++s.z正在使用preincrement运算符,这意味着首先增加s.z的值,然后将其打印出来。然而,s.z++正在使用postincrement运算符,这意味着首先打印s.z的值然后再增加。

答案 2 :(得分:1)

++ sz的意思是“向sz添加1然后使用它”,s.z ++表示“使用sz然后添加1”...为了回答你的主要问题,请回答这个简单的问题:在你的课堂上“特殊系列“你是否覆盖”isClose()“方法?你能把代码放进去吗?

答案 3 :(得分:1)

静态变量与类相关联。因此,一旦将z从9增加到10,只要程序正在运行,它就会保持为10。此外,瞬态变量y在反序列化期间不会获得任何值,因此其值为0(int变量的默认值)。

答案 4 :(得分:0)

请记住,静态变量属于类级别。

对象序列化在对象级别完成。因此序列化和反序列化不会对静态变量计数产生影响。

由于y是瞬态的,因此它将被设置为默认值,在读取对象后为0。

答案 5 :(得分:0)

System.out.print(++s.z + " "); 

输出为10,因为您的对象在内存中,序列化不会擦除瞬态字段,它只是在序列化时忽略它们。

 System.out.println(s2.y + " " + s2.z);

输出为0和10,0,因为y是瞬态字段,它不保存在bean序列化中,因此在反序列化时它获取默认值,对于int,则为0。

10是因为z是静态字段,这意味着它没有与实例连线,序列化也不会删除它。

它是平等的:

s2.z and SpecialSerial.z

答案 6 :(得分:0)

System.out.print(++s.z + " ");  

这会将z增加1,然后将其打印出来。

因为z是静态的,所以所有实例都是相同的,因此在反序列化后它也是10。它不再是9,因为你在序列化之前增加了值。

y为0,因为它声明了瞬态,这意味着它不会成为序列化对象的一部分。因此,在进行反序列化时不会设置任何值。