Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An enum constant contains all the enum constants of the same enum class

Tags:

java

enums

I just realized that an enum constant in Java seems containing all the enumeration constants of the same type.

For example, the following code is legitimate:

enum State {
    enable, disable, deleted;
}

class Test {
    public static void main(String[] args) {
        for ( State s : State.enable.disable.values() ) {
            System.out.println(s);
         }
    }
}

I was very surprised when I saw that the output is:

enable
disable
deleted

Isn't it counter-intuitive or even illogical that the enable constant contains disable constant which in turn constains all the State enum constants?

What is the possible consideration behind this language design?

like image 292
Naitree Avatar asked Jun 06 '15 08:06

Naitree


3 Answers

Designers made a mistake when they first designed Java: static members, which belong to the class itself, and not to any instance of the class, can be accessible using an instance of the class. consider this class:

class Foo {
    public static int bar = 0;
}

You should normally access the bar variable using

int i = Foo.bar;

But you can also do

Foo foo = new Foo();
int i = foo.bar;

That's what's happening here. enable, disable, values(), are static members of the class State that should be accessed using State.enable, State.disable and State.values(). But enable and disable are also instances of the class State, and can thus also be used to access static members of the class:

State state = State.enable;
State state2 = state.disable;

or simpler:

State state2 = State.enable.disable;

Uglier, you could even do that without getting a NullPointerException:

State state = null;
State[] allStates = state.values();
like image 63
JB Nizet Avatar answered Oct 16 '22 23:10

JB Nizet


values() is a static method. The Java language allows you to call a class's static method on any instance of that class, but the instance is ignored.

Same for enable, disable and deleted, which are static fields.

State.enable doesn't contain disable; rather, State.enable.disable is treated the same as State.disable. And State.enable.disable.values() is treated the same as State.disable.values(), which is treated the same as State.values(), which of course returns an array of all three values.

like image 25
user253751 Avatar answered Oct 16 '22 21:10

user253751


.values() is an implicit static method on the enum and no matter on which value are you invoking it, you'll get the same result as State.values().

It's pretty much the same are you were invoking a static method on an instance (instead by directly referring the class name).

Actually, invoking static methods on instances, should raise a warning, which hints that you're doing improperly.

like image 4
Konstantin Yovkov Avatar answered Oct 16 '22 22:10

Konstantin Yovkov