所以我有我的枚举
public enum Sample {
ValueA{
@Override
public String getValue(){ return "A"; }
},
ValueB{
@Override
public String getValue(){ return "B"; }
public void doSomething(){ }
};
abstract public String getValue();
};
我还有一些其他代码试图使用枚举。
Sample.ValueB.doSomething();
它似乎应该有效,但会产生错误“方法doSomething()未定义类型Sample”。与
相反Sample value = Sample.ValueB;
value.doSomething();
产生相同的错误,似乎合理。
我认为有一个合理的答案,为什么第一个不起作用,它与两个例子相同。我希望有人可以指出我为什么会那样的文件。
答案 0 :(得分:15)
“字段”ValueA
的类型为Sample
。这意味着您只能调用ValueA
提供的Sample
上的方法。来自JLS §8.9.1. Enum Constants:
只有当它们覆盖封闭枚举类型中的可访问方法时,才可以在封闭枚举类型之外调用在这些类主体中声明的实例方法。
更重要的是:从设计角度来看enum
值应该是统一的:如果某个特定值可以进行某些操作,那么它应该可以包含所有值(尽管可能会导致执行不同的代码)。
答案 1 :(得分:10)
基本上Sample.ValueB
的编译时类型仍为Sample,即使该值的执行时类型为ValueB
。因此,您的两个代码片段是等效的 - 客户端无法看到“额外”方法,这些方法仅存在于您的枚举值的部分中。
你可以有效地将enum视为声明这样的字段:
public static final Sample ValueB = new Sample() {
@Override
public String getValue(){ return "B"; }
public void doSomething(){ }
};
答案 2 :(得分:4)
写作时
enum Sample
{
Value{
public void doSomething()
{
//do something
}
};
}
您没有创建Sample
枚举的实例,而是enum Sample
的匿名子类的实例。这就是方法doSomething()
未定义的原因。
更新:这可以证明如下:
试试这个
System.out.println(Sample.ValueB.getClass().getName());
打印Sample$2
这意味着即使您在名为doSomething()
的{{1}}实例中有方法Sample$2
,您也可以通过类型{{的超类引用来引用它。 1}}因此只有在类ValueB
中定义的那些方法才能在编译时可见。
您可以通过反射在运行时调用Sample
。
答案 3 :(得分:3)
public void doSomething(){ }
与private void doSomething(){ }
具有相同的效果。
doSomething()
添加到doSomething()
,否则 Sample
在ValueB外部不可见。
每个Sample
值的类型都为Sample
,因此不能为不同的值设置不同的方法(从外部角度来看)。