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

2022-09-01 14:42:35

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

如何通过覆盖方法在java枚举中使用字段?

但我不明白的是,为什么首先会发生错误。

下面是编写为枚举的示例:

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();
}

在实现中,它无法访问 。但是,在抽象类情况下,它可以。FIRSTenumsomeField

此外,添加可以解决问题,删除字段上的修饰符也是如此。superprivate

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


答案 1

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

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“静态嵌套类”一章中所述:

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

因此需要 .如果字段是 而不是 ,也可以使用 。superthisprotectedprivate


答案 2

解析标识符后,Java 优先选择词法作用域而不是继承的成员。因此,当您有一个扩展外部类的内部类并使用外部类的字段而不使用 or 时,将访问外部实例的字段,如果内部类是,则访问该字段,如果内部类是,则失败。相反,在 使用时,您可以显式访问继承的成员。请注意,类是隐式的。您甚至可以使用 来访问继承的成员,但是如果已声明,则必须使用 来访问它。thissuperstaticsuperenumstaticthis((MyClass)this).someFieldprivate