gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 21:08:36 26 4
gpt4 key购买 nike

任务是用java enum实现漂亮的策略设计模式:

public enum MyEnum {

FIRST {
@Override
public String doIt() {
return "1: " + someField; //error
}
},
SECOND {
@Override
public String doIt() {
return "2: " + someField; //error
}
};

private String someField;

public abstract String doIt();

}

但是当提到 someField 我得到

Cannot make a static reference to the non-static field someField.

出了什么问题,有没有可能做得更好?

最佳答案

一个专门的 enum 只不过是一个具有内部类语义的子类。如果您在编译后查看字节码,您会注意到编译器仅插入访问器方法来读取私有(private)字段,但任何专门的枚举都被编译为自己的类。您可以考虑将您的 enum 实现为:

public abstract class MyEnum {

private static class First extends MyEnum {

@Override
public String doIt() {
return "1: " + someField; //error
}
}

private static class Second extends MyEnum {

@Override
public String doIt() {
return "2: " + someField; //error
}
}

public static final MyEnum FIRST = new First();
public static final MyEnum SECOND = new Second();

private String someField;

public abstract String doIt();
}

如您所见,同样的编译器错误也会发生。实际上,您的问题与 enum 无关,而是与它们的内部类语义有关。

但是,您发现编译器猜测您的代码的意图并试图警告您您的意图是非法的。一般来说,someField 字段对任何专门的enum 都是可见的。但是,有两种方法可以从内部类访问 private 字段,只有一种是合法的:

  1. private 成员不会被继承。因此,当 this 实例在父类(super class)中定义时,您无法访问 private 字段。

  2. 对于内部类,外部类的成员是可访问的,即使它们是private。这是由编译器通过将访问器方法插入外部类来实现的,这些外部类通过访问器方法公开 private 字段。只有当内部类是非static 时,才能访问非static 字段。然而对于 enums,内部类总是 static

后面的条件是编译器提示的:

Cannot make a static reference to the non-static field someField

您正试图从 static 内部类访问非 static 字段。即使由于内部类语义,该字段在技术上是可见的,但这是不可能的。您可以通过从父类(super class)中读取值来显式指示编译器访问该值,例如:

public String doIt() {
MyEnum thiz = this;
return thiz.someField;
}

现在编译器知道您正在尝试访问可见(外部)类型的成员,而不是错误地访问(非静态)外部类实例的 someField 字段(它不会存在)。 (类似地,你可以编写 super.someField 来表达你想要沿着继承链而不是访问外部实例的字段的相同想法。)然而,更简单的解决方案是简单地创建该字段 protected 。这样,编译器就会对继承可见性感到满意并编译您的原始设置。

关于java - java - 如何通过覆盖方法来使用java枚举中的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25010763/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com