哈希码为serialVersionUid

时间:2018-11-21 05:10:33

标签: java serialization hashcode serialversionuid

我在一篇文章中读到,JVM提供的默认serialVersionUid是对象的哈希码。如果我们不重写类中的hashcode方法,那么在反序列化期间如何计算哈希码,因为通常hashcode是对象的内存地址?

2 个答案:

答案 0 :(得分:1)

  

我在一篇文章中读到,JVM提供的默认serialVersionUid是对象的哈希码。

那是不正确的。 (或者文章不正确,或者您误读了/误解了。)

可序列化类的默认串行版本UID与hashCode完全无关。

此处描述了生成默认序列版本UID的算法:

基本上,它从类名称,修饰符,接口名称以及其字段,构造函数和方法的签名创建SHA-1哈希。然后,它将获取哈希的前8个字节,并将它们组合成long

答案 1 :(得分:1)

我认为你误会了。不是hashcodeserialVersionUid是静态变量,hashcode是实例方法,对象的哈希码值随对象的不同而变化。

serialVersionUid是根据类的结构(字段,方法等)计算的。它在http://download.oracle.com/javase/6/docs/platform/serialization/spec/serialTOC.html中指定 http://download.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100获取确切格式。

该规范描述了没有提供任何值会发生什么,但是自动生成使用相同的算法。

流中的项目顺序如下:

  • 类名。

  • 以32位整数形式编写的类修饰符。

  • 每个接口的名称按名称排序。

  • 对于按字段名称排序的类的每个字段(私有字段除外) 静态和私有瞬态字段:

    • 字段名称。
    • 以32位整数形式编写的字段的修饰符。
    • 字段的描述符。
  • 如果存在类初始值设定项,则写出以下内容:

    • 方法的名称。
    • 方法的修饰符, java.lang.reflect.Modifier.STATIC,写为32位整数。
    • 方法的描述符()V。
  • 对于按方法名称和签名排序的每个非私有构造函数:

    • 方法的名称。
    • 方法的修饰符,写为32位整数。
    • 方法的描述符。
  • 对于按方法名称和签名排序的每个非私有方法:

    • 方法的名称。
    • 方法的修饰符写为 32位整数。
    • 方法的描述符。
    • SHA-1算法在DataOutputStream产生的字节流上执行,并产生五个32位值sha [0..4]。 哈希值由SHA-1消息摘要的第一和第二个32位值组成。如果消息摘要的结果(五个32位字H0 H1 H2 H3 H4)位于五个名为sha的整数值的数组中,则哈希值的计算方式如下:
    • long hash =((sha [0] >>> 24)&0xFF)|

      ((sha [0] >>> 16)&0xFF)<< 8 |

      ((sha [0] >>> 8)&0xFF)<< 16 |

      ((sha [0] >>> 0)&0xFF)<< 24 |

      ((sha [1] >>> 24)&0xFF)<< 32 |

      ((sha [1] >>> 16)&0xFF)<< 40 |

      ((sha [1] >>> 8)&0xFF)<< 48 |

      ((sha [1] >>> 0)&0xFF)<< 56;

这里没有long hash被引用hashcode