2

In Java Enum is a special kind of datatype, by looking at the word datatype I got few questions like does it have predefined memory size in memory or Are the elements in Enum set to any data structure like Queue for fast access.

As per Java doc

The enum declaration defines a class (called an enum type). The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum.

Why the compiler adds special methods to enum. Could anybody shed light on this?

Source

Thanks in advance?

MaheshVarma
  • 2,081
  • 7
  • 35
  • 58

3 Answers3

4

Why the compiler adds special methods to enum.

So that you can easily get at the values of the enum type, basically.

The only extra methods are valueOf and values. In addition, there are public static final fields, one for each value of the type - again, so that you can actually access the constrainted set of values of that type.

Imagine that the compiler didn't add valueOf and values methods (or at least the values method) - how would you access "all the values of the enum type"? It's often a useful thing to do.

Now EnumSet provides similar facilities, but to get "all the values" you have to provide a Class<> reference, which can be a pain. The values method is somewhat simpler to invoke (although potentially more expensive as well).

See the JLS section 8.9 for more details of exactly what's provided.

To answer the matter of how the values are stored, it's specified that there's a static field per value, but as an implementation detail the Oracle Java compiler also includes a static field with an array - that array is basically cloned in the values method.

You can see this for yourself:

enum Foo {
    BAR, BAZ;
}

Compile:

javac Foo.java

Decompile:

javap -private Foo

Compiled from "Foo.java"
final class Foo extends java.lang.Enum<Foo> {
  public static final Foo BAR;
  public static final Foo BAZ;
  private static final Foo[] $VALUES;
  public static Foo[] values();
  public static Foo valueOf(java.lang.String);
  private Foo();
  static {};
}

If you use javap -c you'll see that values() is basically:

public static Foo[] values() {
    return (Foo[]) $VALUES.clone();
}

The static initializer block creates the limited set of instances and sets the fields.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • could you provide or clarify, "how by adding valueOf and values methods we can access all the values of enum types." It raised another question in me :) @Jon Skeet – MaheshVarma May 30 '13 at 17:35
  • In addition to the static `values` and 'valueOf`, you also get `name` and `ordinal` methods for the `enum` values. – Arend May 30 '13 at 17:37
  • @MaheshVarma: What do you mean? The compiler adds those methods, and you call them. What do you not understand? – Jon Skeet May 30 '13 at 17:37
  • @Arend: Yes, but they're part of the `Enum` class itself, not added by the compiler to each enum class. – Jon Skeet May 30 '13 at 17:37
  • There's also [`MyEnum.class.getEnumConstants()`](http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getEnumConstants%28%29). – JAB May 30 '13 at 17:46
  • @Jon skeet Yes, I understood but my doubt is why compiler adds those 2 methods and how come we access with those methods? – MaheshVarma May 30 '13 at 18:32
  • @MaheshVarma: I said: the compiler adds those two methods to make it easy to get at all values, or the value by name. What do you mean by "how come we access with those methods"? – Jon Skeet May 30 '13 at 20:23
  • "The values method is somewhat simpler to invoke (although potentially more expensive as well)" - can you clarify why you think `values` might be more expensive than `EnumSet.allOf` - which I think is the alternative you had in mind? – Arend May 31 '13 at 13:21
2

The Java Enum is not really all that special.

It is a class.

The elements within an Enum are objects that are instances of the class.

There are some subtle differences. An Enum may not have a constructor as part of it's exported API for obvious reasons. The JVM goes to some lengths to assure that only one single instance of each element is created, even if serializable. For this reason, you can use == to test Enum elements, even though this is highly inadvisable for other kinds of objects.

Yes, the Java compiler adds predefined methods to the Enum, but you are also free to include your own. In fact, while an Enum may not extend another class, it is perfectly allowable for an Enum to implement an interface.

TL;DR: Regard Java Enums as a special case of a Class with some predefined methods for convenience. The elements are objects of the class.

scottb
  • 9,908
  • 3
  • 40
  • 56
1

You can use GrepCode to look at java.lang.Enum which is the class all enum types extend. Hopefully that will shed some light on the implementation. By the way, there is also a .toString() and an .ordinal() method in addition to valueOf() and values() that are part of enum types. There are standard methods like .equals and .hashcode that are part of the values within the enum. So there's a lot of available functionality.

Scott Shipp
  • 2,241
  • 1
  • 13
  • 20