0

我有以下代码:

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++”相同?

4

7 回答 7

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确实会用从文件中反序列化的值覆盖静态值。

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

于 2013-06-28T08:49:30.810 回答
1

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

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

“++sz”和“s.z++”一样吗?

++s.z正在使用 preincrement 运算符,这意味着首先增加值s.z然后打印它。而s.z++使用后增量运算符,这意味着先打印值,s.z然后再递增。

于 2013-06-28T08:50:55.753 回答
1

++sz 的意思是“给 sz 加 1 然后使用它”,s.z++ 的意思是“使用 sz 然后加 1”...为了回答你的主要问题,请回答这个简单的问题:在你的课堂上“特别系列”你重写了“isClose()”方法吗?可以放代码吗?

于 2013-06-28T08:51:55.843 回答
1

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

于 2013-06-28T08:52:16.363 回答
0

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

对象序列化是在对象级别完成的。所以序列化和反序列化对静态变量计数没有影响。

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

于 2013-06-28T08:48:11.823 回答
0
System.out.print(++s.z + " "); 

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

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

输出为 0 和 10,0 因为 y 是瞬态字段,它不保存在 bean 序列化中,所以在反序列化时它得到默认值,witch 为 0 表示 int。

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

它是相等的:

s2.z and SpecialSerial.z
于 2013-06-28T08:49:27.453 回答
0
System.out.print(++s.z + " ");  

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

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

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

于 2013-06-28T08:50:54.637 回答