JDK-6709903 : (reflect) Class.isEnum() doesn't work for advanced or "specialized" enums
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2008-06-03
  • Updated: 2012-09-28
  • Resolved: 2008-06-10
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
1.5.0_12-b04, 1.6.0_06-b02 and 1.7.0-ea-b25

A DESCRIPTION OF THE PROBLEM :
import static java.lang.System.out;

import java.util.Arrays;

public class TestMe {
    enum Works { AH, BH, CH}
    
    enum Eon {
        HADEAN("hadean"){@Override
        int value() {return 10;}},
        ARCHAEAN("archaean"){@Override
        int value() {return 3;}},
        PROTEROZOIC("proterozoic"){@Override
        int value() {return 8;}},
        PHANEROZOIC("phanerozoic"){@Override
        int value() {return 9;}};

        String text;
        abstract int value();
        
        Eon(String s) {
            text = s;
        }
        
        String text() {
            return text;
        }
    }

    public static void main(String... args) {
        Class<?> c = null;
        Eon eon = null;
        
        try {
            c = (args.length == 0 ? Eon.class : Class.forName(args[0]));
            out.format("Enum name:  %s%nEnum constants:  %s%n",
                   c.getName(), Arrays.asList(c.getEnumConstants()));
            if (c.isEnum()) {
            out.format("  Eon.values():  %s%n", Arrays.asList(Eon.values()));
            }
            
            eon = Eon.HADEAN;
            System.out.println("Test: " + eon.text() + "   Value: " + eon.value());
            
        } catch (ClassNotFoundException x) {
            x.printStackTrace();
        }
      
        Works works = Works.AH;
        Class<? extends Enum<?>> cl1 = eon.getClass ();
        Class<? extends Enum<?>> cl2 = works.getClass ();
        
        Object y = null;
        
        try {
            if (cl2.isEnum() ) { // IS TRUE
                y = cl2.getEnumConstants ()[0];
            } else {
                y = cl2.newInstance();
            }
            
            System.out.println("Object2: " + y);
        } catch (Exception ee) {
            ee.printStackTrace ();
        }
        
        try {
            if (cl1.isEnum() ) { // IS FALSE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                y = cl1.getEnumConstants ()[0];
            } else {
                y = cl1.newInstance(); // Consequently crashes here.
            }
            
            System.out.println("Object1: " + y);
        } catch (Exception ee) {
            ee.printStackTrace ();
        }
    }
}


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run as java application.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The excerpt should recognize BOTH classes as Enums.

ACTUAL -
Only the "simple enum definition is recognized as Enum in "isEnum()", albeit they both are enums.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.InstantiationException: com.boeing.mma.rts.aha.enums.TestMe$Eon$1
	at java.lang.Class.newInstance0(Class.java:340)
	at java.lang.Class.newInstance(Class.java:308)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import static java.lang.System.out;

import java.util.Arrays;

public class TestMe {
    enum Works { AH, BH, CH}
    
    enum Eon {
        HADEAN("hadean"){@Override
        int value() {return 10;}},
        ARCHAEAN("archaean"){@Override
        int value() {return 3;}},
        PROTEROZOIC("proterozoic"){@Override
        int value() {return 8;}},
        PHANEROZOIC("phanerozoic"){@Override
        int value() {return 9;}};

        String text;
        abstract int value();
        
        Eon(String s) {
            text = s;
        }
        
        String text() {
            return text;
        }
    }

    public static void main(String... args) {
        Class<?> c = null;
        Eon eon = null;
        
        try {
            c = (args.length == 0 ? Eon.class : Class.forName(args[0]));
            out.format("Enum name:  %s%nEnum constants:  %s%n",
                   c.getName(), Arrays.asList(c.getEnumConstants()));
            if (c.isEnum()) {
            out.format("  Eon.values():  %s%n", Arrays.asList(Eon.values()));
            }
            
            eon = Eon.HADEAN;
            System.out.println("Test: " + eon.text() + "   Value: " + eon.value());
            
        } catch (ClassNotFoundException x) {
            x.printStackTrace();
        }
      
        Works works = Works.AH;
        Class<? extends Enum<?>> cl1 = eon.getClass ();
        Class<? extends Enum<?>> cl2 = works.getClass ();
        
        Object y = null;
        
        try {
            if (cl2.isEnum() ) { // TRUE
                y = cl2.getEnumConstants ()[0];
            } else {
                y = cl2.newInstance();
            }
            
            System.out.println("Object2: " + y);
        } catch (Exception ee) {
            ee.printStackTrace ();
        }
        
        try {
            if (cl1.isEnum() ) { // FALSE !!!!!!
                y = cl1.getEnumConstants ()[0];
            } else {
                y = cl1.newInstance();
            }
            
            System.out.println("Object1: " + y);
        } catch (Exception ee) {
            ee.printStackTrace ();
        }
    }
}
---------- END SOURCE ----------

Comments
EVALUATION Duplicate of 6708424.
10-06-2008

EVALUATION Here's an extremely compressed version of the provided test case: public class Test { enum E{ A, B{} }; public static void main(String... args) { System.out.println(E.A.getClass().isEnum()); System.out.println(E.B.getClass().isEnum()); } } OUTPUT: $ javac Test.java && java Test true false Specialized enum constants such as E.B do not set the ACC_ENUM bit since the anonymous inner class used to implement them are not enum classes. Closing this issue as "not a bug". For additional info, see 5020490.
04-06-2008