对象的编组和解组

46

对象编组和解组是什么意思?当上述操作发生时,即序列化对hashCodeequals的影响,会对对象状态产生什么影响?

6个回答

56
将一个对象进行标记化,就是将其转换为适合于序列化存储或传输的形式;也就是说,将其从JVM内存中的原生形式转换为可发送到电线、插入文件/数据库等形式的形式。具体细节取决于所涉及的标记化形式;Java的默认序列化机制是一种方式,但将对象转换为XML或JSON表示同样有效。
反向过程的解析只是这个过程的相反/另一侧;采用由标记创建的对象的表示形式,并使用它在JVM中重新构建对象实例。
老实说,我不确定你的问题的其他部分确切的意思。原始对象通常不会被标记化改变(这是概念上类似于只读操作,如复制)。因此,它的哈希码等仍然保持不变。
对象的未经标记化的副本将根据定义具有与原始对象相同的逻辑状态(毕竟,这就是标记化的目的,能够再现等效的对象)。因此,在这方面,它的状态,即其字段的值,是相同的。但是,如果哈希码取决于环境因素-例如计算机的主机名或实例存储的内存地址,那么它可能会报告不同的结果。这特别关注默认Object.hashCode()实现,因为对象的内存位置很重要。(但这与标记化无关;通过任何方式在同一JVM中采取“完美副本”仍将导致在这种情况下不同的哈希码。)

很好地解释了答案。 - Kasun Siyambalapitiya

38

marshalling 指的是生成一系列字节流,其中包含足够的信息以便能够重新构建对象。

这不会影响原始对象,它是只读操作。unmarshalling 会导致创建另一个不相关的对象(通常情况下)。

复制可能具有相同的hashCode()并且equals() == truecompareTo() == 0(假设它是可比较的)。


但是我听说在编组时,像equals、hashcode这样的计算代码不会被包括进去。彼得,是这样吗? - Harshana
只包含足够的状态(具体取决于对象)以重建对象,不包括代码(类文件)。 - Thilo
它们可以在取消编组后重新计算。 - user425367
通常只发送原始数据,而不发送派生值(如果需要也可以发送)。通常代码也不会被发送,但是Java RMI也支持这样做。例如,您可以将一个对象发送到另一个没有该类代码的系统中,并且它可以正常工作。 - Peter Lawrey
4
基本上与序列化/反序列化完全相同的意思。 - zinking
这会增加额外的费用。 - undefined

1

编组(Marshaling)与序列化(Serialization)几乎相同。区别在于远程对象处理,如rfc2713中所指定的(在Java上下文中)。

至于哈希码值:它取决于对象如何计算其哈希码。如果仅从字段计算,则显然与未编组的对象相等。但是,如果使用Object的原始hashCode,则它将是JVM给该对象的任意值,并且会因实例而异。


0
在C++中,如果您通用地从存储对象的内存块生成哈希码,则未解组对象中的哈希码可能会不同。
首先,指针值是不同的。其次,由于系统加载器对二进制文件进行了重定位,因此vtbl指针也是不同的。

0

它用于保存对象或将它们发送到另一个Java世界中的VM,例如。 如果您已经编排了所有信息,则在编排后,对象将被重建为相同的对象。

例如,您可以标记字段,以便在序列化过程中丢失它们,然后无法完全重新创建对象。

很可能状态会丢失,这是因为通常不会序列化状态,而只会序列化bean所持有的数据。例如,您序列化字段地址。您不会序列化状态“2个人当前正在查看该对象”。


-4

编组是将对象中存在的数据转换为XML格式并以XML格式查看它,而取消编组则是其反向操作,将XML文件转换为对象。


1
外部格式可以是XML,但也可以是其他格式。当进行RMI时,它是另一种“外部”格式。 - André Schild
Java中的编组和解组可以通过JAXB概念实现,而JAXB是Java架构XML绑定,它告诉我们如何将Java对象转换为XML格式。我对RMI的另一种外部格式一无所知,如果您愿意分享任何相关信息,我将不胜感激。谢谢! - SMB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接