Java 调用enum';s法
我有以下枚举:Java 调用enum';s法,java,enums,Java,Enums,我有以下枚举: enum Days{ TODAY{ @Override public Date getLowerBound(){ another(); //1 currentUpperBound(); //2 return null; } @Override public Date another() {
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
编译得好吗?这两种方法都是非静态的。我看不出有什么问题。。。也许这和日食有关
更新:正如@Florian Schaetz在评论中所注意到的,如果我们声明该方法具有
static private
修饰符,它将正常工作。为什么?我建议将currentUpperBounds()
设置为受保护的而不是私有的。另一种解决方案是在您的通话前加上super.
,这也适用于:
@Override
public Date getLowerBound(){
another();
super.currentUpperBound();
return null;
}
@Override
public Date getLowerBound(){
another();
TODAY.currentUpperBound();
return null;
}
或者,今天也可以:
@Override
public Date getLowerBound(){
another();
super.currentUpperBound();
return null;
}
@Override
public Date getLowerBound(){
another();
TODAY.currentUpperBound();
return null;
}
Mick Mnemonic在这篇文章中提到了一个很好的答案,这很好地解释了这个问题。您可以将
currentUpperBound
方法声明为abstract
,并在您的实例中实现它,或者让它保持实现状态
在这两种情况下,都应该使用非privateaccess修饰符声明它
这里的编译器错误消息非常混乱。
它假定currentUpperBound
应该是static
,这将允许您从实例访问,即使该方法声明为private
TL;博士
解决你的问题
我建议将currentUpperBound()
方法设置为protected
为什么?
您应该考虑< En强大>每个枚举值作为匿名代码子类<代码>天< /代码> <强>。此外,由于枚举必须保证其每个值都是唯一的(例如,您可以使用
=
测试相等性),它存储为静态最终
字段(因此也有使用大写字母命名枚举值的习惯)
理解幕后的枚举
代码等价
要显示有关枚举如何工作的一些代码,请执行以下操作1:
(几乎)相当于:
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
的equals(Object)
在这里是完美的,因为它只测试这一点
-为什么可以从MyEnum
继承方法,或者访问private static
方法,但不能访问private
非静态方法
- 这些值存储为
字段,因此它们无法访问实例上下文静态
- 值inherit
,因此任何可以通过legacy访问的内容都对他们可见MyEnum
开关
能够判断枚举的每个值是否有大小写
:尝试只测试一些值,而不定义默认值
,编译器将发出警告。如果只是使用带有常量的抽象类,这是不可能的
values()
方法还表明,与我的简单示例相比,情况更加复杂,但我认为这有助于理解
1根据我对的理解,第二个不是抽象的。这意味着它必须是枚举上下文中的静态。私有方法不能重写make currentUpperBound()公开。错误消息很混乱。我理解问题所在,是的。我会让他们使用默认的访问修饰符。谢谢。我想知道为什么错误是完全不相关的。虽然将其更改为
protected
或public
可以修复它。它是否由于某种原因与静态上下文相关。以及将方法更改为静态修复错误也是…:O@Codebender我也是,但我认为这一直都是eclipse。从技术上讲,将方法定义为静态方法也是可行的。似乎今天可以访问静态私有,但不能访问非静态私有。有趣的是,我们必须对此进行一些阅读。@FlorianSchaetz确实很有趣。为什么静态私有方法有效?但这是doesn没有提供静态私有的原因。JSL说,enum主体是一个匿名类,不是静态类。但可能与此有关。@FlorianSchaetz我在吃午餐时想到了它,认为我更了解它在幕后的工作原理。我修改了我的答案,并有兴趣选择你我想我发现了另一个有趣的细节:你实际上可以调用私有的非静态方法。你只需要使用super.
。所以在你的例子中super.unreactlemethod()
在重写的sayMyName
方法中起作用。在整个事情变得容易之前…在它前面加上MyEnum。
也起作用。有趣的是,但慢慢地我意识到我对Java的理解是多么零碎,尤其是在细节方面。有关更多细节,请参阅中的优秀答案。