为什么枚举实现不能访问枚举类中的私有字段

我刚才通过说如何解决编译问题来回答这个问题:

如何通过重写方法来使用java enum中的字段?

但我不明白为什么错误发生在一开始。

以下是以枚举forms编写的示例:

public enum MyEnum { FIRST { @Override public String doIt() { return "1: " + someField; //error } }, SECOND { @Override public String doIt() { return "2: " + super.someField; //no error } }; private String someField; public abstract String doIt(); } 

这与抽象类完全相同

 abstract class MyClass { class FIRST extends MyClass { @Override public String doIt() { return "1: " + someField; //no error } }; class SECOND extends MyClass { @Override public String doIt() { return "2: " + super.someField; //no error } }; private String someField; public abstract String doIt(); } 

对于enum实现中的FIRST ,它无法访问someField 。 但是在抽象类的情况下它可以。

另外,添加super修复了问题,就像删除字段上的private修饰符一样。

有谁知道为什么这种轻微的怪癖会发生在行为中?

你的抽象类不等同于你的枚举,因为枚举是隐式公共静态最终的。 因此,如果您使用以下内容,您将观察到相同的行为:

 abstract class MyClass { static class FIRST extends MyClass { @Override public String doIt() { return "1: " + someField; // error } }; static class SECOND extends MyClass { @Override public String doIt() { return "2: " + super.someField; // no error } }; private String someField; public abstract String doIt(); } 

如http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html中的 “静态嵌套类”一章所述:

静态嵌套类不能直接引用其封闭类中定义的实例变量或方法:它只能通过对象引用来使用它们。

因此需要super 。 如果字段protected而非private您也可以使用this

解析标识符时,Java优先于inheritance成员的词法范围。 因此,当你有一个内部类扩展外部类并使用外部类的字段而不使用thissuper ,外部实例的字段将被访问,如果内部类是static ,则该字段将失败,因为那时没有外部实例。 相反,当使用super您将显式访问inheritance的成员。 请注意, enum类是隐式static 。 您甚至可以使用this来访问inheritance的成员,但是如果它被声明为private ,则必须使用((MyClass)this).someField来访问它。

FIRST类是MyClass的内部类,也是子类。 在访问someField时没有看到错误的原因是因为您正在访问外部类的someField ,而不是超类。

 class MyClass { class FIRST extends MyClass { @Override public String doIt() { super.someField = "super"; return "1: " + someField; } }; private String someField = "outer"; public String doIt(){return "";} public static void main(String[] args) { System.out.println(new MyClass().new FIRST().doIt()); } } 

印刷品1: outer

在另一种情况下,你的枚举常量表现为静态嵌套子类,而不是内部类,因此它们没有对外部类的引用,只有它们的超类。

我不同意接受的答案。

枚举const声明是隐式的public static final ,而不是enum const所属的类。

来自JSL Chapter 8.Classes

枚举常量的可选类主体隐式定义了一个匿名类声明(第15.9.5节),该声明扩展了直接封闭的枚举类型。 类主体由匿名类的通常规则管理。

什么是“无序阶级规则”?

来自JSL第15章:

Java编译器自动从类实例创建表达式派生匿名类声明。

匿名类永远不是抽象的(第8.1.1.1节)。

匿名类总是隐式最终的(第8.1.1.2节)。

匿名类始终是内部类(第8.1.3节); 它永远不会是静态的(§8.1.1,§8.5.1)。

如果枚举等效类是静态类,如何解释以下错误?

 public enum MyClass { First { public static int b; //(2)Illegal static declaration in inner class }; } 

但是为什么内部类不能访问外部类的字段?

可能的枚举等效类可能如下所示,它给出了与枚举类相同的错误:

 abstract class MyClass { private int someField; static { class First extends MyClass { public void method() { System.out.println(someField); } private static int b; } } } 

更多:

  • 嵌套枚举是静态的?
  • 如何实现枚举?