Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6421053
Votes 0
Synopsis Enum hashCode is order dependent
Category java:classes_lang
Reported Against
Release Fixed
State 11-Closed, Not a Defect, bug
Priority: 4-Low
Related Bugs 6277781
Submit Date 03-MAY-2006
Description
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 :
 customer  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.
Posted Date : 2006-05-03 07:57:51.0
Work Around
N/A
Evaluation
Enums are handled specially by serialization and not actually
copied over the wire.
Posted Date : 2006-05-03 08:47:03.0
Comments
  
  Include a link with my name & email   

Submitted On 02-OCT-2008
slowfly
I've got JDK 1.6.4, the problem still exists...

CATEGORICAL 4384790
NUMERICAL 9634993

NUMERICAL 4384790
CATEGORICAL 9634993



PLEASE NOTE: JDK6 is formerly known as Project Mustang