[ACCEPTED]-How is values() implemented for Java 6 enums?-enums

Accepted answer
Score: 118

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

Given this simple enum:

public enum Stuff {
   COW, POTATO, MOUSE;
}

You 4 can actually look at the code that Java 3 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 2 classes by making a temporary directory 1 and running:

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

If you assign it to a local variable the 11 only thing that you can modify is assigning 10 another enum to this variable. This will 9 not change the enum itself because you are 8 only changing the object your variable references.

It 7 seems that the enums are in fact singletons 6 so that only one element from each enum 5 can exist in you whole program this makes 4 the == operator legal for enums.

So there 3 is no performance problem and you can't 2 accidentally change something in your enum 1 definition.

Score: 1

Is the code for it native? Or does the JVM 19 / compiler treat it specially, only returning 18 a new instance from values() when it cannot 17 prove that it will not be modified.

1) No. Or 16 at least not in current implementations. See 15 @lucasmo's answer for the evidence.

2) AFAIK, no.

Hypothetically 14 it could do this. However, proving that 13 an array is never modified locally would 12 be complicated and relatively expensive 11 for the JIT to perform. If the array "escapes" from 10 the method that called values(), it gets more complex 9 & more expensive.

The chances are that 8 this (hypothetical) optimization would 7 not pay off ... when averaged over all Java 6 code.

The other issue is that this (hypothetical) optimization 5 might open up security holes.


The interesting 4 thing though is that the JLS does not seem 3 to specify that the values() member returns an array 2 copy. Common sense1 says that it must do ... but 1 it is not actually specified.

1 - It would be a gaping security hole if values() returned a shared (mutable) array of enum values.

More Related questions