I was looking through the documentation and source code, because I wanted to be certain that values() would always return an array in the order in which the Enum values are declared. Turns out, it's not in the documentation as far as I can tell.
I checked the source code for the Enum class, and no luck (there is a related, private "getValues" method).
So I'm guessing that some compiler/interpreter-foo is already going on to create a class that extends Enum out of a declaration like:
public static enum MyEnum
So is values() also statically translated into a hardcoded array during compilation? Or is it actually a method called at runtime, and if so, where is it defined?
The values()
method is part of the definition of the enum
type. Not to be confused with the Enum
base class. The formal definition is in the Section 8.9 of the JLS which does specify the order returned matches the order in which they are declared.
As you can see from the bytecode below obtained by disassemlbing an enum, the values()
method on the enums simply return a copy of the private static
array which contains all the declared enum constant. This array ENUM$VALUES
is filled in a static initilization block.
DaysOfTheWeek.java
public enum DaysOfTheWeek {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
DaysOfTheWeek.java disassembled
After the static block, the bytecode marked 0-92 initializes the enum constants, the bytecode marked 94-139 puts those constants in an array and the bytecode marked 140 assigns the array to the ENUM$VALUES
static field of the class. The code in the values()
method simply creates a copy of the array assigned to the ENUM$VALUES
field by calling System.arraycopy
on it and returns the copy.
Compiled from "DaysOfTheWeek.java"
public final class DaysOfTheWeek extends java.lang.Enum{
public static final DaysOfTheWeek MONDAY;
public static final DaysOfTheWeek TUESDAY;
public static final DaysOfTheWeek WEDNESDAY;
public static final DaysOfTheWeek THURSDAY;
public static final DaysOfTheWeek FRIDAY;
public static final DaysOfTheWeek SATURDAY;
public static final DaysOfTheWeek SUNDAY;
static {};
Code:
0: new #1; //class DaysOfTheWeek
3: dup
4: ldc #18; //String MONDAY
6: iconst_0
7: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V
10: putstatic #23; //Field MONDAY:LDaysOfTheWeek;
13: new #1; //class DaysOfTheWeek
16: dup
17: ldc #25; //String TUESDAY
19: iconst_1
20: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V
23: putstatic #26; //Field TUESDAY:LDaysOfTheWeek;
26: new #1; //class DaysOfTheWeek
29: dup
30: ldc #28; //String WEDNESDAY
32: iconst_2
33: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V
36: putstatic #29; //Field WEDNESDAY:LDaysOfTheWeek;
39: new #1; //class DaysOfTheWeek
42: dup
43: ldc #31; //String THURSDAY
45: iconst_3
46: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V
49: putstatic #32; //Field THURSDAY:LDaysOfTheWeek;
52: new #1; //class DaysOfTheWeek
55: dup
56: ldc #34; //String FRIDAY
58: iconst_4
59: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V
62: putstatic #35; //Field FRIDAY:LDaysOfTheWeek;
65: new #1; //class DaysOfTheWeek
68: dup
69: ldc #37; //String SATURDAY
71: iconst_5
72: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V
75: putstatic #38; //Field SATURDAY:LDaysOfTheWeek;
78: new #1; //class DaysOfTheWeek
81: dup
82: ldc #40; //String SUNDAY
84: bipush 6
86: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V
89: putstatic #41; //Field SUNDAY:LDaysOfTheWeek;
92: bipush 7
94: anewarray #1; //class DaysOfTheWeek
97: dup
98: iconst_0
99: getstatic #23; //Field MONDAY:LDaysOfTheWeek;
102: aastore
103: dup
104: iconst_1
105: getstatic #26; //Field TUESDAY:LDaysOfTheWeek;
108: aastore
109: dup
110: iconst_2
111: getstatic #29; //Field WEDNESDAY:LDaysOfTheWeek;
114: aastore
115: dup
116: iconst_3
117: getstatic #32; //Field THURSDAY:LDaysOfTheWeek;
120: aastore
121: dup
122: iconst_4
123: getstatic #35; //Field FRIDAY:LDaysOfTheWeek;
126: aastore
127: dup
128: iconst_5
129: getstatic #38; //Field SATURDAY:LDaysOfTheWeek;
132: aastore
133: dup
134: bipush 6
136: getstatic #41; //Field SUNDAY:LDaysOfTheWeek;
139: aastore
140: putstatic #43; //Field ENUM$VALUES:[LDaysOfTheWeek;
143: return
public static DaysOfTheWeek[] values();
Code:
0: getstatic #43; //Field ENUM$VALUES:[LDaysOfTheWeek;
3: dup
4: astore_0
5: iconst_0
6: aload_0
7: arraylength
8: dup
9: istore_1
10: anewarray #1; //class DaysOfTheWeek
13: dup
14: astore_2
15: iconst_0
16: iload_1
17: invokestatic #51; //Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V
20: aload_2
21: areturn
public static DaysOfTheWeek valueOf(java.lang.String);
Code:
0: ldc #1; //class DaysOfTheWeek
2: aload_0
3: invokestatic #59; //Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #1; //class DaysOfTheWeek
9: areturn
}
I'll add to Devon's answer, that the values()
method is added by the compiler, by definition.
From the enums tutorial:
The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With