我有以下枚举:
enum Days{
TODAY{
@Override
public Date getLowerBound(){
another(); //1
currentUpperBound(); //2
return null;
}
@Override
public Date another() {
return null;
}
};
public abstract Date getLowerBound();
public abstract Date another();
private Date currentUpperBound(){
return null;
}
}
为什么//2
会导致编译时错误
Cannot make a static reference to the non-static method
currentUpperBound() from the type Days
但//1
编译好吗?两种方法都是非静态的。我看不出任何问题......也许它与Eclipse有关?
更新: 正如@Florian Schaetz在评论中注意到的,如果我们声明方法具有static private
修饰符,它将正常工作。为什么呢?
答案 0 :(得分:9)
我建议currentUpperBounds()
保护而不是私有。另一个解决方案是使用super.
为您的呼叫添加前缀,这也适用于:
@Override
public Date getLowerBound(){
another();
super.currentUpperBound();
return null;
}
或者,TODAY也有效:
@Override
public Date getLowerBound(){
another();
TODAY.currentUpperBound();
return null;
}
Mick Mnemonic在这个duplicate中提到了很好的答案,这很好地解释了它。
答案 1 :(得分:4)
我建议使用currentUpperBound()
方法protected
。
您应该将枚举的每个值视为Days
的匿名子类。此外,由于枚举必须保证其每个值都是唯一的(例如,您可以测试与==
的相等),它将存储为static final
字段(因此还有用大写字母命名枚举值的习惯。
显示关于枚举如何工作的一些代码 1 :
public enum MyEnum {
JESSE {
@Override
public void sayMyName() {
System.out.println("Pinkman");
}
}, WALTER;
public void sayMyName() {
System.out.println("Heisenberg");
}
private void unreachableMethod() {
// try again
}
}
(几乎)相当于:
public class MyEnum {
private static final MyEnum JESSE = new MyEnum() {
@Override
public void sayMyName() {
System.out.println("Pinkman");
}
};
private static final MyEnum WALTER = new MyEnum();
public void sayMyName() {
System.out.println("Heisenberg");
}
private void unreachableMethod() {
// try again
}
}
当你以这种方式写作时,有些事情变得更容易理解:
==
用于测试枚举等式每个值只有一个指针。 Object
' s equals(Object)
在这里非常完美,因为它仅测试它。
MyEnum
继承方法或访问private static
方法,而不是private
非静态方法static
字段,因此无法访问实例上下文。MyEnum
,因此可以通过遗产访问任何内容。枚举机制中嵌入了一些额外的控件。
例如,switch
能够判断枚举的每个值是否有case
:尝试仅测试一些值而不定义default
,编译器将发出警告。如果您只是使用带常量的抽象类,那么这是不可能的。
values()
方法也表明事物比我的简单例子更进化,但我认为这有助于理解。
1 基于我对JSL 的理解
答案 2 :(得分:3)
您可以将currentUpperBound
方法声明为abstract
并在您的实例中实施,也可以将其保留。
在这两种情况下,您都应使用非private
访问修饰符声明它。
这里的编译器错误消息非常混乱。
它假设currentUpperBound
应为static
,即使该方法声明为private
,也会授予您对实例的访问权限。