Java 枚举:每个实例的独占方法
从中我了解到,在Java中,可以为枚举的每个实例定义特定的方法:Java 枚举:每个实例的独占方法,java,compiler-construction,syntax,enums,Java,Compiler Construction,Syntax,Enums,从中我了解到,在Java中,可以为枚举的每个实例定义特定的方法: public class AClass { private enum MyEnum{ A { public String method1(){ return null; } }, B { public Object method2(String s){ return null; } }, C { public void method3(){ return null; } }
public class AClass {
private enum MyEnum{
A { public String method1(){ return null; } },
B { public Object method2(String s){ return null; } },
C { public void method3(){ return null; } } ;
}
...
}
我感到惊讶的是,这甚至是可能的,这个特定于每个实例的“独占方法”是否有一个名称来查找文档
还有,应该如何使用它?因为下一步不是编译:
private void myMethod () {
MyEnum.A.method1();
}
如何使用这些“独占”方法?您需要在枚举中声明抽象方法,然后在特定的枚举实例中实现这些方法
class Outer {
private enum MyEnum {
X {
public void calc(Outer o) {
// do something
}
},
Y {
public void calc(Outer o) {
// do something different
// this code not necessarily the same as X above
}
},
Z {
public void calc(Outer o) {
// do something again different
// this code not necessarily the same as X or Y above
}
};
// abstract method
abstract void calc(Outer o);
}
public void doCalc() {
for (MyEnum item : MyEnum.values()) {
item.calc(this);
}
}
}
您不能引用这些方法,因为您正在为每个枚举有效地创建匿名(*)类。由于它是匿名的,所以只能从匿名类本身内部或通过反射引用此类方法 当您在枚举中声明抽象方法并分别为每个枚举实现该方法时,此技术最为有用
(*)JLS 8.9 enum部分说:“enum常量的可选类体隐式定义了一个匿名类声明(§15.9.5),该声明扩展了立即封闭的enum类型。”每个
enum
都是一个匿名内部类。因此,与任何匿名内部类一样,您可以添加所需的所有方法,但无法在类之外引用它们,因为该类没有定义方法的类型
允许在enum
实现上使用方法的优点是,它允许策略模式,其中enum本身具有抽象方法或默认实现,并且enum
的特定成员具有该方法的实现,这些实现可能会做一些不同的事情
我已经使用这种技术大大降低了switch语句的代码复杂性。与其在其他类中打开枚举,只需获取对它的引用并调用一个方法,然后让枚举本身处理它。当然,这取决于场景是否合理,但它可以极大地降低代码复杂性。如果他希望所有实例共享一个方法,但有单独的实现,根据我收集的信息,我认为情况并非如此。没错,我希望每个实例都有“特定的方法”,因为java似乎允许它。。。在我看来,这个答案并没有回答我提出的两个问题中的任何一个。@Sanjay:终于有了一个有意义的答案@edutesoy:如果您希望针对每个枚举实现特定的方法(即,每个枚举的
doCalc
不同),请使用我提供的方法。否则,您可以在枚举上使用普通方法(不放在特定的枚举实例中),所有枚举实例都可以访问这些方法。@Sanjay,我否决了它,因为它不符合我的答案,请您修改您的答案以满足我提出的问题好吗?特别是,如何访问MyEnum.A.method1();(或对其不可能的某些解释)而不修改Enum(在Java语言中似乎是合法的)。只是想更好地理解枚举,而不是面对任何实际问题。我很乐意接受。谢谢!那么,为什么Java允许这样做呢?你有没有提到过这种特殊性?@edutesoy:JLS 8.9 Enums part说:“enum常量的可选类体隐式定义了一个匿名类声明(§15.9.5),该声明扩展了立即封闭的enum类型。”但我引用它是错误的。。。当然,您可以从匿名类本身内部引用此类方法。还应该可以通过反射引用它,如果您猜到匿名类的名称(最终不是那么匿名),也可以通过((Enum$0)A).method()引用它。。。并不是说我会用它(我甚至不确定它是否有效)。我建议你在回答中添加最后一条评论。我会接受的。谢谢@edutesoy:好的,是这样的。我对我的答案稍加修改,以使其仍然有意义;不编译,因为编译器只知道MyEnum.A是MyEnum类型,并且您尚未为此枚举声明任何方法。您要查找的“名称”是枚举定义中的任意一个类。@彼得:对不起,我在完成之前发布了注释。@安德烈亚斯:我已经删除了我的过时注释:)请注意,虽然目前不可能这样做,但在将来的Java版本中,它也会作为一个匿名的内部类出现在表中。。。没有办法在课堂之外引用它们。它是匿名的这一事实是一个技术问题;您仍然可以通过其隐式类型访问该方法:newobject(){public void foo(){}}.foo()代码>。我看不出为什么枚举常量在直接引用时不能以相同的方式工作。