给定以下枚举类型:
enum Repeat {
Daily,
Weekly,
Yearly
}
我意识到我们可以这样写:
Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;
等价于:
Repeat repeat = Repeat.Weekly;
我可以知道为什么允许这种语法吗?有没有办法让编译器警告我们避免这种情况?
由于Daily,Weekly,Yearly
是枚举
中的静态
字段,并持有Repeat
对象,所以这是允许的。此外,编译器会发出警告"The static field Repeat.Weekly should be accessed in a static way"
。这类似于下面的代码行。
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.
这是Repeat
枚举类型的字节码检查的部分,从中可以明确得知Enum
变量是static
的,并且保存了枚举对象本身。
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
枚举实例只是枚举类的静态实例。
我们有两种方式访问一个类的静态字段:
当你链式调用你的枚举时:
Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;
TypeName.staticMember
TypeName.staticMethod()
或者在一个实例上:
new TypeName().staticMember
new TypeName().staticMethod()
Repeat.Daily.Weekly.Yearly.Weekly
就像上面的第二段代码片段一样,在实例引用上访问静态成员。class Type {
static Type INSTANCE1, INSTANCE2, INSTANCE3;
}
可以使用Type.INSTANCE1.INSTANCE2.INSTANCE3
来引用INSTANCE3
。这是有效的,但不是好的实践。
static
:则对Primary表达式进行求值,并且结果被丢弃。 [...] 字段访问表达式的结果是在Primary表达式类型的类或接口中指定的类变量的值。 - Radiodef