ferekdoley
ferekdoley

Reputation: 149

Why does Java allow two (or more) enums to be referenced when only the last is recognised?

I stumbled across this and was wondering is there a reason that java allows it.

Here is a sample of what I mean:

public enum Days {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}

public class EnumTest {

    public static void main(String[] args) {

        methodThatDoesSomething(Days.FRIDAY);
    }

    public static void methodThatDoesSomething(Days day){

        System.out.println(day);
    }
}

The output for this is FRIDAY, as would be expected.

If I change the code like so:

public class EnumTest {

    public static void main(String[] args) {

        methodThatDoesSomething(Days.FRIDAY.MONDAY);
    }

    public static void methodThatDoesSomething(Days day){

        System.out.println(day);
    }
}

The output for this is MONDAY.

I also receive the warning:

The static field Days.MONDAY should be accessed in a static way

but it still compiles and runs.

Any example of when this multiple enum reference could be used would be much appreciated.

Upvotes: 1

Views: 161

Answers (3)

Dariusz
Dariusz

Reputation: 22271

An enum is actually a class with special syntactic sugar to make it's usage simpler.

You are actually accessing an instance of Days which is actually Enum, and then accessing that instance's static class member.

So this is possible due to class hierarchy and Java's class static member handling.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502106

This isn't a matter of enums in particular - it's just about any static member also (unfortunately) being valid via an expression of that type. The most common example is:

Thread thread = new Thread(...);
thread.start();
thread.sleep(1000); // This doesn't do what it looks like

For a non-enum example which is closer to your original, it's basically like this:

class Foo {
   public static final Foo X = null;
   public static final Foo Y = new Foo();
}

public class Test {
    public static void main(String[] args) {
        Foo foo = Foo.X.Y;
    }
}

Note that even though Foo.X is null, you don't get a null pointer exception here, although strangely the generated code does still access Foo.X before ignoring it completely. It's as if it's written:

Foo ignored = Foo.X;
Foo foo = Foo.Y;

Basically, this was a mis-step in language design for Java, and it's too late to fix it now - the best we can do is get warnings and then fix the code to access static members via the class name.

Upvotes: 9

BobTheBuilder
BobTheBuilder

Reputation: 19294

The code works as expected, but not what you really asked for.

Days.FRIDAY.MONDAY

is just like

Days.MONDAY

But accessing MONDAY from a non static reference instead of static reference as you should ( and that's the reason for the warning)

Upvotes: 2

Related Questions