JDK-6424491 : Cannot initialise nested enums
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2006-05-11
  • Updated: 2011-02-16
  • Resolved: 2006-07-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b91Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000
5.00.2195
Service Pack 4

A DESCRIPTION OF THE PROBLEM :
This may be a feature of the enum implementation than a bug but I have found it a problem that when nesting enums of the same type, the order they are declared affects whether the nested values are initialised or not.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Employ nested enums and use nested values that reference undeclared primary values.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
enum1:AAA
index:0
text:text1
nested:BBB

enum2:BBB
index:1
text:text2
nested:CCC

enum3:CCC
index:2
text:text3
nested:AAA
ACTUAL -
enum1:AAA
index:0
text:text1
nested:null

enum2:BBB
index:1
text:text2
nested:null

enum3:CCC
index:2
text:text3
nested:AAA

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class test {
    
    public FaultyEnum f1,f2,f3;

    public enum FaultyEnum {
	AAA(0, FaultyEnum.BBB, "text1"),
	BBB(1, FaultyEnum.CCC, "text2"),
	CCC(2, FaultyEnum.AAA, "text3"),
	DDD(3, FaultyEnum.EEE, "text4"),
	EEE(4, FaultyEnum.BBB, "text5");
	
	private final int index;
	
	private final FaultyEnum nested;
	
	private final String text;
	
	FaultyEnum(int i, FaultyEnum f, String s) {
	    index= i;
	    nested= f;
	    text= s;
	}
	
	public int index() {
	    return index;
	}
	
	public FaultyEnum nest() {
	    return nested;
	}
	
	public String text() {
	    return text;
	}
    }
    
    public static void main(String[] args) {
	test t = new test();
	t.f1= FaultyEnum.AAA;
	t.f2= FaultyEnum.BBB;
	t.f3= FaultyEnum.CCC;

	System.out.println("enum1:" + t.f1);
	System.out.println("index:" + t.f1.index());
	System.out.println("text:" + t.f1.text());
	System.out.println("nested:" + t.f1.nest()+"\n");

	System.out.println("enum2:" + t.f2);
	System.out.println("index:" + t.f2.index());
	System.out.println("text:" + t.f2.text());
	System.out.println("nested:" + t.f2.nest()+"\n");

	System.out.println("enum3:" + t.f3);
	System.out.println("index:" + t.f3.index());
	System.out.println("text:" + t.f3.text());
	System.out.println("nested:" + t.f3.nest()+"\n");
    }
    
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use an index variable and an index lookup to return the nested enum values you require eg.

------------------------------------------------------------------

public class test {
    
    public FaultyEnum f1,f2,f3;

    public enum FaultyEnum {
	AAA(0, 1, "text1"),
	BBB(1, 2, "text2"),
	CCC(2, 0, "text3"),
	DDD(3, 4, "text4"),
	EEE(4, 1, "text5");
	
	private final int index;
	
	private final int nestedindex;
	
	private final String text;
	
	FaultyEnum(int i, int ni, String s) {
	    index= i;
	    nestedindex= ni;
	    text= s;
	}
	
	public int index() {
	    return index;
	}
	
	public FaultyEnum nest() {
	    return match(nestedindex);
	}
	
	public String text() {
	    return text;
	}

	public static FaultyEnum match(int i) {
	    for (FaultyEnum f : FaultyEnum.values()) {
		if (f.index() == i)
		    return f;
	    }
	    return null;
	}
    }
    
    public static void main(String[] args) {
	test t = new test();
	t.f1= FaultyEnum.AAA;
	t.f2= FaultyEnum.BBB;
	t.f3= FaultyEnum.CCC;

	System.out.println("enum1:" + t.f1);
	System.out.println("index:" + t.f1.index());
	System.out.println("text:" + t.f1.text());
	System.out.println("nested:" + t.f1.nest()+"\n");

	System.out.println("enum2:" + t.f2);
	System.out.println("index:" + t.f2.index());
	System.out.println("text:" + t.f2.text());
	System.out.println("nested:" + t.f2.nest()+"\n");

	System.out.println("enum3:" + t.f3);
	System.out.println("index:" + t.f3.index());
	System.out.println("text:" + t.f3.text());
	System.out.println("nested:" + t.f3.nest()+"\n");
    }
    
}

Comments
EVALUATION This is a compiler bug. The JLS clearly says that you may not refer to an enum constant declared to the right of this enum constant. This is why the program will not compile if changed to: AAA(0, BBB, "text1"), BBB(1, CCC, "text2"), CCC(2, AAA, "text3"), DDD(3, EEE, "text4"), EEE(4, BBB, "text5");
11-05-2006