简体   繁体   English

为什么我们允许在Java中引用枚举成员的枚举成员?

[英]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? 有没有办法让编译器警告我们不要这样做?

This is allowed as Daily, Weekly, Yearly are the static field by default inside the enum and holds the object of Repeat . 这是允许的,因为Daily, Weekly, Yearly都是enum defaultstatic字段,并保持Repeat的对象。 Also, you will get a warning from the compiler "The static field Repeat.Weekly should be accessed in a static way" . 此外,您将收到编译器的警告"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. 下面是Repeat枚举的字节码检查的一部分,从中可以清楚地看出, Enum变量是static并且保存Enum本身的对象。

   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 

Enum instance are just static instance of the enum class. 枚举实例只是枚举类的static实例。

We have two way to access static field of a class: 我们有两种访问类的静态字段的方法:

  1. Via class itselft: Repeat.Daily 通过类itselft:Repeat.Daily
  2. Via instance of class: Repeat.Daily.Daily 通过类的实例: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. 就像从类的实例中获取静态字段一样。

Is there a way to let compiler warn us against this? 有没有办法让编译器警告我们不要这样做?

Yes, use a good IDE and turn on warning. 是的, 使用一个好的IDE并打开警告。 That way, you'll be notified as soon as your write the code, before you even compile it. 这样,在编写代码之前,您将立即收到通知,然后再进行编译。

Eg in Eclipse , it is called "Non-static access to static member": 例如,在Eclipse中 ,它被称为“对静态成员的非静态访问”:

在此输入图像描述

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. 因为枚举文字只是静态成员, Repeat.Daily.Weekly.Yearly.Weekly就像上面的第二个代码片段,访问实例引用上的静态成员。

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 . 并且可以使用Type.INSTANCE1.INSTANCE2.INSTANCE3获取对INSTANCE3的引用。 It's valid, but it's bad practice. 这是有效的,但这是不好的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM