How is values() implemented for Java 6 enums?

enums, java

Solution

Basically, the compiler (javac) translates your enum into a static array containing all of your values at compile time. When you call values(), it gives you a .clone'd() copy of this array.

Given this simple enum:

public enum Stuff {
   COW, POTATO, MOUSE;
}

You can actually look at the code that Java generates:

public enum Stuff extends Enum<Stuff> {
    /*public static final*/ COW /* = new Stuff("COW", 0) */,
    /*public static final*/ POTATO /* = new Stuff("POTATO", 1) */,
    /*public static final*/ MOUSE /* = new Stuff("MOUSE", 2) */;
    /*synthetic*/ private static final Stuff[] $VALUES = new Stuff[]{Stuff.COW, Stuff.POTATO, Stuff.MOUSE};

    public static Stuff[] values() {
        return (Stuff[])$VALUES.clone();
    }

    public static Stuff valueOf(String name) {
        return (Stuff)Enum.valueOf(Stuff.class, name);
    }

    private Stuff(/*synthetic*/ String $enum$name, /*synthetic*/ int $enum$ordinal) {
        super($enum$name, $enum$ordinal);
    }
}

You can look at how javac 'translates' your classes by making a temporary directory and running:

javac -d <output directory> -XD-printflat filename.java

Problem

In Java, you can create an enum as follows: ``` public enum Letter { A, B, C, D, E, F, G; static { for(Letter letter : values()) { // do something with letter } } } ``` This question concerns the "values()" method. Specifically, how is it implemented? Usually, I could jump to the source for Java classes using F3 or CTRL+Click in Eclipse (even for classes like String, Character, Integer, and even Enum). It is possible to view the source of the other enum methods (e.g., valueOf(String)). Does "values()" create a new array each time it is invoked? If I assign it to a local variable and then modify one of the elements, what happens (clearly this won't affect the value returned by values(), which implies that a new array is allocated each time). Is the code for it native? Or does the JVM / compiler treat it specially, only returning a new instance from values() when it cannot prove that it will not be modified.

Original source

Related problems