Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6421053

Enum hashCode is order dependent

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 5.0
    • core-libs
    • x86
    • windows_xp

      FULL PRODUCT VERSION :
      $ java -version
      java version "1.5.0_05"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      Suppose you have an Enum with two values. The hashCode for those
      values is dependent on the order in which hashCode is called on them.

      The first value to have hashCode called on it always gets the same code, regardless of its ordinal or other associated with data. This leads to a big problem when enums are handed from one JVM instance to another (say via a
      socket or some other serialization.) In that case, the two values' equals
      method will still evaluate to true, but they have different values of hashCode,
      breaking the contract (among other things).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the code below. The code defines an Enum with two values (NUMERICAL and CATEGORICAL). One instance of each gets put in a list, which we then shuffle. The list is iterated over, and hashCode called on its elements,
      so that about 1/2 of the time we're calling hashCode on NUMERICAL, and the
      other half on CATEGORICAL.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      About 1/2 of the time I should see something like:
      CATEGORICAL 20392474
      NUMERICAL 11352996

      The other half, I should see:
      NUMERICAL 11352996
      CATEGORICAL 20392474

      The order of NUMERICAL / CATEGORICAL has swapped, but the same number stays associated with them.
      ACTUAL -
      About 1/2 of the time I get:
      CATEGORICAL 20392474
      NUMERICAL 11352996

      But the other half are:
      NUMERICAL 20392474
      CATEGORICAL 11352996

      The hashes for NUMERICAL and CATEGORICAL have been swapped.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.ArrayList;
      import java.util.Collections;

      public class EnumHash {

      public enum TDTDataType {
      NUMERICAL,
      CATEGORICAL;
      }

      public synchronized void doit()
      {
      ArrayList<TDTDataType> l = new ArrayList<TDTDataType>();
      l.add(TDTDataType.NUMERICAL);
      l.add(TDTDataType.CATEGORICAL);
      Collections.shuffle(l);
      for (TDTDataType type : l)
      {
      System.out.println(type + " " +type.hashCode());
      }
      }

      public static void main(String[] args) {
      EnumHash e = new EnumHash();
      e.doit();
      }

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Can't trust that hashCode will be the same on enum values that cross a JVM
      boundary, so you have to wrap the values in some other class that computes a
      hashCode on other attributes of the value.

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: