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.
values() method can be used to return all values present inside the enum. Order is important in enums.By using the ordinal() method, each enum constant index can be found, just like an array index. valueOf() method returns the enum constant of the specified string value if exists.
Enums are statically created when the enum class is first loaded and are immutable. You must have a constructor in the enum class if you want to assign different values to your enum. After the constructor was finished you cannot change the enums value (immutable as said).
You cannot create an object of an enum explicitly so, you need to add a parameterized constructor to initialize the value(s). The initialization should be done only once. Therefore, the constructor must be declared private or default. To returns the values of the constants using an instance method(getter).
The Java compiler internally adds the values() method when it creates an enum. The values() method returns an array containing all the values of the enum.
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
If you assign it to a local variable the only thing that you can modify is assigning another enum to this variable. This will not change the enum itself because you are only changing the object your variable references.
It seems that the enums are in fact singletons so that only one element from each enum can exist in you whole program this makes the == operator legal for enums.
So there is no performance problem and you can't accidentally change something in your enum definition.
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