序列化是否保留对象标识? [英] Does serialization preserve object identity?

查看:155
本文介绍了序列化是否保留对象标识?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java Serializable 接口和 ObjectOutputStream 来序列化对象(到目前为止,这个方法一直是足以满足我的目的)。

I am using the Java Serializable interface and the ObjectOutputStream to serialize objects (until now, this method has been sufficient for my purposes).

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

My API relies on object identity for some operations and I’m wondering if it will be preserved by serialization. That is to say: if, for two arbitrary objects a and b, it holds a == b before serialization, does it still hold after deserialization?

我发现了一些< a href =http://orionl.blogspot.com/2007/01/why-java-serialization-is-bad.html\"rel =noreferrer>声称相反 - 但他们要么写了一篇关于旧版本的JRE(我只对1.6和1.5感兴趣),或者关注RMI(与我无关)。

I’ve found some texts that claim the contrary – but they either wrote about an older version of the JRE (I’m only interested in 1.6 and perhaps 1.5), or were concerned with RMI (which is not relevant for me).

文档不是很快。 sun.com上的技术文章提到 ObjectOutputStream 在对象上使用缓存,这对我来说只有在确实保留了对象标识时才有意义,但我没有足够的信心依赖这些脆弱的证据。

The documentation isn’t very forthcoming regarding object identity. A technical article on sun.com mentions that ObjectOutputStream uses caching on objects, which to me only makes sense if the object identity is indeed preserved but I’m not confident enough to rely on this flimsy evidence.

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

I’ve tried it out (Java 1.6, OS X) and found that yes, the identity of objects remains unchanged by serialization. But can I extrapolate from these results or are they unreliable?

对于我的测试,我已经序列化了以下对象图:

For my test, I’ve serialized the following object graph:

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,如果它在序列化之前保持== b,则在反序列化后仍然保持为真如下:

For two arbitrary objects a and b, if it holds a == b before serialization, it will still hold true after deserialization IF:


  1. 两者都是和b被写成并随后作为相同流的部分读取。以下是来自 ObjectInputStream 文档的引用:图表使用参考共享机制正确恢复对象。

  2. a和b的类不会覆盖 readResolve()有可能改变引用的恢复方式;包含a和b的类。

  1. Both a and b are written as and subsequently read from as parts of the same stream. Here's a quote from ObjectInputStream documentation: "Graphs of objects are restored correctly using a reference sharing mechanism."
  2. Class of a and b does not override readResolve() that has the potential of changing how references are restored back; neither do classes that hold a and b.

对于所有其他情况,不会保留对象标识。

For all other cases, object identity will NOT be preserved.

这篇关于序列化是否保留对象标识?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆