benf.org :  other :  cfr :  How are Enums implemented?

Aside - Enums

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

A little history

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.

Original code

public enum EnumTest1 {
    FOO,
    BAR,
    BAP
}

Decompiled with CFR 0_6

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