为什么枚举实现不能访问枚举类中的私有字段
我刚才通过说如何解决编译问题来回答这个问题:
如何通过重写方法来使用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成员的词法范围。 因此,当你有一个内部类扩展外部类并使用外部类的字段而不使用this
或super
,外部实例的字段将被访问,如果内部类是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; } } }
更多:
- 嵌套枚举是静态的?
- 如何实现枚举?