Reputation: 42760
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
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":
Upvotes: 2
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
Reputation: 18235
Enum instance are just static
instance of the enum class.
We have two way to access static field of a class:
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
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