如何调用Enum个人方法?

我的枚举可能看起来像下面的那个。 我的目标是使用一些常用方法(我通过添加抽象方法强制执行此方法)和一些“枚举值单独”方法。

以下代码编译:

 public enum MyEnum { VALUE { @Override public void syso() { System.out.println("VALUE syso"); } }, SPECIAL_VALUE { @Override public void syso() { System.out.println("SPECIAL_VALUE syso"); } public void sayHello() { System.out.println("Hello"); } }; public abstract void syso(); public static void main(String... args) { MyEnum.VALUE.syso(); MyEnum.SPECIAL_VALUE.syso(); } } 

运行此结果将打印以下内容:

 VALUE syso SPECIAL_VALUE syso 

但是,尝试调用我在SPECIAL_VALUE定义的sayHello()是行不通的。

将以下内容添加到main方法中,不再编译:

 public static void main(String... args) { MyEnum.SPECIAL_VALUE.sayHello(); // does not work } 

这是为什么? 对我来说似乎完全没问题,但找不到方法。 有没有办法调用这个方法? 也许通过反思?

我想避免使这个方法变得抽象,因为它对任何其他枚举值都没有意义。 我也无法extend这个枚举并添加这个特殊的方法,同时inheritance常见的方法。 我还想避免添加某种单例类来“模拟”这个。

无论如何可以运行它? 如果没有,那么什么是我最好的选择呢?

这是为什么?

原因在JLS中给出:

8.9.1。 枚举常量

枚举类主体中声明的实例方法只有在覆盖枚举类型(第8.4.8节)中覆盖可访问方法时才可以在封闭枚举类型之外调用

有没有办法调用这个方法? 也许通过反思?

鉴于上述约束,如果您不希望在封闭的枚举类中公开该方法,则reflection是唯一的替代方法。 每个枚举常量都创建为内部类,例如MyEnum$1MyEnum$2 。 因此,您可以通过常量的getClass()方法检索Class ,然后通过reflection调用您的方法(省略exception处理):

 ... Class c = MyEnum.SPECIAL_VALUE.getClass(); Method m = c.getMethod("sayHello"); m.invoke(MyEnum.SPECIAL_VALUE); ... 

我很可能会尝试避免reflection并在枚举类中公开该方法,并让它抛出UnsupportedOperationException

 ... public void sayHello() { throw new UnsupportedOperationException(); } ... 

这至少会在运行时捕获非预期的调用 – 它仍然不允许编译器在编译期间捕获它们,但reflection方法也不会。

因为SPECIAL_VALUEenum的实例, enum只有方法syso()你正在调用

类与以下内容相同:

 interface Foo { Foo inst1 = new Foo() { @Override public void doFoo() { } public void doAnonymous() { } }; void doFoo(); } 

你不能像Foo.inst1.doAnonymous()一样调用方法doAnonymous(),你只能通过reflection访问doAnonymous