Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is values() implemented for Java 6 enums?

Tags:

java

enums

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.

like image 280
les2 Avatar asked Jul 22 '09 04:07

les2


People also ask

What is the purpose of values () method in enum?

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.

How are enums implemented?

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).

Can we assign values to enum in Java?

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).

Which method is used in Java to get the values of an enum?

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.


2 Answers

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 
like image 144
lucasmo Avatar answered Oct 21 '22 23:10

lucasmo


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.

like image 35
Janusz Avatar answered Oct 21 '22 21:10

Janusz