gpt4 book ai didi

java - 序列化是否保留对象身份?

转载 作者:IT老高 更新时间:2023-10-28 20:40:59 25 4
gpt4 key购买 nike

我正在使用 Java Serializable 接口(interface)和 ObjectOutputStream 来序列化对象(到目前为止,这种方法已经足够满足我的目的了)。

我的 API 依赖于对象身份进行某些操作,我想知道它是否会被序列化保留。也就是说:如果,对于两个任意对象ab,在序列化之前持有a == b,是不是反序列化后仍然保持?

我发现了一些 claim the contrary 的文本——但他们要么写过旧版本的 JRE(我只对 1.6 和 1.5 感兴趣),要么关注 RMI(与我无关)。

documentation关于对象身份不是很明确。一个 technical article在 sun.com 上提到 ObjectOutputStream 对对象使用缓存,这对我来说只有在对象身份确实被保留的情况下才有意义,但我没有足够的信心依赖这个脆弱的证据。

我试过了(Java 1.6,OS X),发现是的对象的身份通过序列化保持不变。但是我可以从这些结果中推断出来还是它们不可靠?

为了我的测试,我序列化了以下对象图:

C----------+
| b1 b2 |
+----------+
| |
v v
B---+ B---+
| a | | a |
+---+ +---+
\ /
\ /
\/
A----+
| |
+----+

最小的复制代码:

import java.io.*;

public class SerializeTest {
static class A implements Serializable {}

static class B implements Serializable {
final A a;

public B(A a) {
this.a = a;
}
}

static class C implements Serializable {
final B b1, b2;

public C() {
A object = new A();
b1 = b2 = new B(object);
}
}

public static void main(String[] args) throws IOException,
ClassNotFoundException {
C before = new C();
System.out.print("Before: ");
System.out.println(before.b1.a == before.b2.a);

// Serialization.
ByteArrayOutputStream data = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(data);
out.writeObject(before);
out.close();

// Deserialization.
ObjectInputStream in =
new ObjectInputStream(new ByteArrayInputStream(data.toByteArray()));
C after = (C) in.readObject();
System.out.print("After: ");
System.out.println(after.b1.a == after.b2.a);
}
}

最佳答案

对于任意两个对象a和b,如果在序列化前持有a == b,反序列化后IF依然成立:

  1. a 和 b 都作为同一流的一部分写入并随后从中读取。这是来自 ObjectInputStream 的引述文档:“使用引用共享机制正确恢复对象图。”
  2. a 和 b 的类不会覆盖 readResolve(),这可能会改变引用的恢复方式;持有 a 和 b 的类也不行。

对于所有其他情况,不会保留对象身份。

关于java - 序列化是否保留对象身份?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1351706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com