【问题标题】:Hashcode as serialVersionUid哈希码作为 serialVersionUid
【发布时间】:2019-04-23 15:22:12
【问题描述】:

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

【问题讨论】:

  • 我假设您的意思是文章 "Discover the secrets of the Java Serialization API",其中说:“您可以使用 JDK 发行版附带的名为 serialver 的实用程序来查看默认情况下该代码是什么(它是默认情况下只是对象的哈希码)。”

标签: java serialization hashcode serialversionuid


【解决方案1】:

我在一篇文章中看到JVM提供的默认serialVersionUid是一个对象的hashcode。

这是不正确的。 (要么文章不正确,要么你误读/误解了它。)

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

这里描述了生成默认串行版本UID的算法:

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

【讨论】:

  • 感谢分享提到生成 SUID 方法的链接。但是它还提到“如果未为某个类声明 SUID,则该值默认为该类的哈希值。”
  • 该哈希是使用我链接到的算法生成的。请再读一遍。
  • Ketan,也许他们应该写“该类的哈希结果”。
  • @MartinAndersson - 这不是 >>a
  • 我明白了 =) 但是谢谢你的澄清。
【解决方案2】:

我想你误会了。不是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 获取确切格式。

规范描述了未提供值时发生的情况,但自动生成使用相同的算法。

流中item的顺序如下:

  • 类名。

  • 写成 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 的五个 int 值的数组中,则哈希值将按如下方式计算:
    • long hash = ((sha[0] >>> 24) & 0xFF) |

      ((sha[0] >>> 16) & 0xFF)

      ((sha[0] >>> 8) & 0xFF)

      ((sha[0] >>> 0) & 0xFF)

      ((sha[1] >>> 24) & 0xFF)

      ((sha[1] >>> 16) & 0xFF)

      ((sha[1] >>> 8) & 0xFF)

      ((sha[1] >>> 0) & 0xFF)

这里long hash 没有提到hashcode

【讨论】:

  • 在JVM中,每个类都会有一个实例。所以文档所说的 hashCode 是关于 Class 实例的......
  • 能否请您分享文档参考。
猜你喜欢
  • 1970-01-01
  • 2011-07-01
  • 2014-12-21
  • 2012-09-16
  • 2014-02-17
  • 2020-12-08
  • 2014-12-31
  • 2013-02-24
  • 1970-01-01
相关资源
最近更新 更多