如何调用Enum个人方法?

时间:2014-11-05 11:11:25

标签: java enums

我的枚举可能看起来像下面的那个。我的目标是使用一些常用方法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

但是,尝试拨打我在sayHello()中定义的SPECIAL_VALUE不起作用。

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

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

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

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

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

2 个答案:

答案 0 :(得分:7)

  

为什么?

原因在JLS

中给出
  

<强> 8.9.1。枚举常数

     

...

     

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

  

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

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

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

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

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

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

答案 1 :(得分:1)

因为SPECIAL_VALUEenum的实例而enum只有方法syso()。您正在调用

以下是类的相同内容:

interface Foo {

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

            public void doAnonymous() {

            }
        };
        void doFoo();
    }

您不能像Foo.inst1.doAnonymous()那样调用方法doAnonymous(),并且只能通过反射访问doAnonymous