繁体   English   中英

对象的序列化(java)

[英]Serialization of Objects (java)

我有以下代码:

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(分别是瞬时值和静态值)应该返回为7和9,这是默认值(请在这一点上对我进行更正,因为我认为该对象在反序列化后得到的值)是默认值)。 语法“ ++ object.var”是什么意思(请参阅(1))。 是否与“ Object var ++”相同,即“ ++ sz”与“ s.z ++”相同?

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

添加:

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覆盖了z的静态值。

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

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

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

“ ++ sz”与“ s.z ++”相同吗?

++sz使用preincrement运算符,这意味着先增加sz的值,然后再打印它。 s.z++使用postincrement运算符,这意味着先打印sz的值,然后再打印。

++ sz的意思是“先将sz加1,然后再使用它”,s.z ++的意思是“先使用sz再加1” ...为了回答您的主要问题,请回答以下简单的问题:在您的类“ Special series”中您重写“ isClose()”方法吗? 可以输入代码吗?

静态变量与类相关联。 因此,将z从9递增到10后,只要程序正在运行,它将保持10。 同样,瞬时变量y在反序列化期间未获得任何赋值,因此其值为0(int变量的默认值)。

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

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

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

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

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

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

输出为0和10,因为y是瞬态字段,所以为0,它不会保存在bean序列化中,因此在反序列化时它将获得默认值,对于int而言,女巫为0。

10是因为z是静态字段,那意味着它不与实例连接,序列化也不会擦除它。

等于:

s2.z and SpecialSerial.z
System.out.print(++s.z + " ");  

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

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

y为0,因为它声明为瞬态,这意味着它将不属于序列化对象。 因此,进行反序列化时不会设置任何值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM