3

I read in an article that the default serialVersionUid provided by JVM is the hashcode of an object. If we don't override the hashcode method in a class, how will the hashcode be computed during deserializatio as normally hashcode is the memory address of object?

Tck
  • 83
  • 6
  • I assume you mean the article ["Discover the secrets of the Java Serialization API"](https://oracle.com/technical-resources/articles/java/serializationapi.html), where it says: "You can use a utility that comes with the JDK distribution called `serialver` to see what that code would be by default (it is just the hash code of the object by default)." – beatngu13 Feb 08 '21 at 21:30

2 Answers2

3

I read in an article that the default serialVersionUid provided by JVM is the hashcode of an object.

That is incorrect. (Either the article is incorrect, or you misread / misunderstood it.)

The default serial version UID for a serializable class is totally unrelated to the hashCode.

The algorithm for generating the defaut serial version UID is described here:

Basically, it creates an SHA-1 hash from the classes name, modifiers, interface names, and the signatures for its fields, constructors and methods. Then it takes the first 8 bytes of the hash and assembles them into a long.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

I think you misunderstood. It is not hashcode. serialVersionUid is static variable and hashcode is instance method and hashcode value of object varies object to object.

serialVersionUid is calculated based on the structure of your class - fields, methods, etc. It is specified in the 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 for the exact format.

The spec describes what happens in no value is provided, but the autogeneration uses the same algorithm.

The sequence of items in the stream is as follows:

  • The class name.

  • The class modifiers written as a 32-bit integer.

  • The name of each interface sorted by name.

  • For each field of the class sorted by field name (except private static and private transient fields:

    • The name of the field.
    • The modifiers of the field written as a 32-bit integer.
    • The descriptor of the field.
  • If a class initializer exists, write out the following:

    • The name of the method, .
    • The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
    • The descriptor of the method, ()V.
  • For each non-private constructor sorted by method name and signature:

    • The name of the method, .
    • The modifiers of the method written as a 32-bit integer.
    • The descriptor of the method.
  • For each non-private method sorted by method name and signature:

    • The name of the method.
    • The modifiers of the method written as a 32-bit integer.
    • The descriptor of the method.
    • The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and produces five 32-bit values sha[0..4]. The hash value is assembled from the first and second 32-bit values of the SHA-1 message digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named sha, the hash value would be computed as follows:
    • 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;

Here long hash is not referred to hashcode

Shiva
  • 1,962
  • 2
  • 13
  • 31