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