Cheok Yan Cheng
Cheok Yan Cheng

Reputation: 42760

Why do we allow referring to an enum member of an enum member in Java?

Given the following enum:

enum Repeat {
    Daily,
    Weekly,
    Yearly
}

I realize we are able to write it this way:

Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;

which is equivalent to:

Repeat repeat = Repeat.Weekly;

May I know why such syntax is allowed? Is there a way to let the compiler warn us against this?

Upvotes: 19

Views: 816

Answers (4)

Andreas
Andreas

Reputation: 159135

Is there a way to let compiler warn us against this?

Yes, use a good IDE and turn on warning. That way, you'll be notified as soon as your write the code, before you even compile it.

E.g. in Eclipse, it is called "Non-static access to static member":

enter image description here

Upvotes: 2

Amit Bera
Amit Bera

Reputation: 7325

This is allowed as Daily, Weekly, Yearly are the static field by default inside the enum and holds the object of Repeat. Also, you will get a warning from the compiler "The static field Repeat.Weekly should be accessed in a static way". It is similar to below lines of code.

class Foo{
    public static Foo obj1 = new Foo();
    public static Foo obj2 = new Foo();
    public static Foo obj3 = new Foo();
}

Foo f = Foo.obj1.obj2.obj3; // will work fine but you will get a warning from the compiler.

Here is some part of bytecode inspection of Repeat enum and from this, it is clear that Enum variable is static and holds the Object of Enum itself.

   0: new           #1                  // class com/java8/demo/Repeat
   3: dup
   4: ldc           #14                 // String Daily
   6: iconst_0
   7: invokespecial #15                 // Method "<init>":(Ljava/lang/String;I)V
  10: putstatic     #19                 // Field Daily:Lcom/java8/demo/Repeat;
  13: new           #1                  // class com/java8/demo/Repeat 

Upvotes: 19

Mạnh Quyết Nguyễn
Mạnh Quyết Nguyễn

Reputation: 18235

Enum instance are just static instance of the enum class.

We have two way to access static field of a class:

  1. Via class itselft: Repeat.Daily
  2. Via instance of class: Repeat.Daily.Daily

When you chain your enum:

Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;

It's just like get a static field from an instance of a class.

Upvotes: 5

ernest_k
ernest_k

Reputation: 45329

Enum literals are static members, and with each static member, one can access them either using the class reference:

TypeName.staticMember
TypeName.staticMethod()

Or on an instance:

new TypeName().staticMember
new TypeName().staticMethod()

The second approach is discouraged (and the compiler will issue a warning)

As enum literals are just static members, Repeat.Daily.Weekly.Yearly.Weekly is like the second code snippet above, accessing static members on instance references.

With a class, that would be:

class Type {
    static Type INSTANCE1, INSTANCE2, INSTANCE3;
}

And one can get a reference to INSTANCE3 using Type.INSTANCE1.INSTANCE2.INSTANCE3. It's valid, but it's bad practice.

Upvotes: 1

Related Questions