benf.org : other : cfr : How are Enums implemented? |
Again, this isn't secret, but it's a nice example of using this decompiler in 'anger' ;), to investigate how Enums are implemented in Java
Prior to java 1.5, there were no enums. The 'simple' way to get something which behaved like a C enum was to use a list of public static final ints.
A better way to do it was to have a class which had no public constructor, only a set of final static instances of itself as members. ('The typesafe enum pattern', in Effective Java (item 21))
Java 1.5 introduced a first class Enum type, described here. Here, I'm using CFR to investigate what they compile down to.
public enum EnumTest1 { FOO, BAR, BAP }
Note that from CFR 0_12, this will resugar correctly - you will need to specify --sugarenums false to get the below output
I've not provided java.lang.Enum, which this class derives, feel free to use CFR to do it yourself ;)
class EnumTest1 extends Enum { // Fields public static final /* enum */ EnumTest1 FOO; public static final /* enum */ EnumTest1 BAR; public static final /* enum */ EnumTest1 BAP; private static final /* synthetic */ EnumTest1[] $VALUES; // Methods public static EnumTest1[] values() { return EnumTest1.$VALUES.clone(); } public static EnumTest1 valueOf(String name) { return Enum.valueOf(org/benf/cfr/tests/EnumTest1, name); } private EnumTest1(String unnamed_local_this_1, int unnamed_local_this_2) { super(unnamed_local_this_1, unnamed_local_this_2); } static void <clinit>() { EnumTest1.FOO = new EnumTest1("FOO", 0); EnumTest1.BAR = new EnumTest1("BAR", 1); EnumTest1.BAP = new EnumTest1("BAP", 2); EnumTest1.$VALUES = new EnumTest1[]{EnumTest1.FOO, EnumTest1.BAR, EnumTest1.BAP}; } }
Yes - it compiles down to almost precisely the pattern described by Bloch in Effective Java for 'typesafe enums' ;)
(there's actually a small difference - there is an 'enum' access flag on the fields, which couldn't be faked up prior to enum support)
Like many changes in Java, 'Enum' is all syntactic sugar - it's nice to see how far people can extend the Java language just via syntactic sugar without requiring new bytecode / runtime support! (though looking at what's involved, I miss plain old C enums!)
nb: There are some small runtime advantages - Serialisation support means you don't have to jump through hoops to ensure enum uniqueness, since language support was specifically introduced.
Last updated 08/2012 |