简体   繁体   English

如何调用Enum个人方法?

[英]How to call Enum individual methods?

I have an enum that might look like the one below. 我的枚举可能看起来像下面的那个。 My goal is to have an enum with some common methods (I enforced this by adding an abstract method) and some "enum value individual" methods. 我的目标是有一个enum的一些常用方法(我通过增加一个抽象方法执行此)和一些“枚举值个人”的方法。

The following code compiles: 以下代码编译:

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();
    }

}

Running this results in the following being printed: 运行此结果会打印以下内容:

VALUE syso
SPECIAL_VALUE syso

However trying to call sayHello() , which I defined in SPECIAL_VALUE , does not work. 但是,尝试调用我在SPECIAL_VALUE定义的sayHello()不起作用。

Adding the following to the main method, does not compile anymore: 将以下内容添加到main方法中,不再编译:

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

Why is that? 这是为什么? It seems perfectly fine to me, but the method cannot be found. 对我来说似乎完全没问题,但找不到方法。 Is there any way to invoke this method? 有没有办法调用这个方法? Maybe via reflection? 也许通过反思?

I would like to avoid making this method abstract as well, because it does not make sense for any other enum values. 我也想避免将这个方法抽象化,因为它对任何其他枚举值都没有意义。 I also cannot extend this enum and add this special method, while inheriting the common ones. 我也无法extend这个枚举并添加这个特殊的方法,同时继承常见的方法。 I would also like to avoid adding some kind of singleton class to "simulate" this. 我还想避免添加某种单例类来“模拟”这个。

Is it anyhow possible to run this? 无论如何可以运行它? If not, what would be my best alternative? 如果没有,那么什么是我最好的选择呢?

Why is that? 这是为什么?

The reason is given in the JLS : 原因在JLS中给出:

8.9.1. 8.9.1。 Enum Constants 枚举常量

... ...

Instance methods declared in enum class bodies may be invoked outside the enclosing enum type only if they override accessible methods in the enclosing enum type (§8.4.8) . 只有当它们覆盖封闭枚举类型(第8.4.8节)中的可访问方法时,才可以在封闭枚举类型外部调用在枚举类主体中声明的实例方法。

Is there any way to invoke this method? 有没有办法调用这个方法? Maybe via reflection? 也许通过反思?

Given the above constraint, reflection is the only alternative if you do not want to expose the method in the enclosing enum class. 鉴于上述约束,如果您不希望在封闭的枚举类中公开该方法,则反射是唯一的替代方法。 Each enum constant is created as an inner class, like MyEnum$1 and MyEnum$2 in your example. 每个枚举常量都创建为一个内部类,如MyEnum$1MyEnum$2 Thus, you can retrieve the Class through the constant's getClass() method and then call your method through reflection (exception handling omitted): 因此,您可以通过常量的getClass()方法检索Class ,然后通过反射调用您的方法(省略异常处理):

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

I would most likely try to avoid reflection and expose the method in the enum class, and let it throw an UnsupportedOperationException : 我很可能会尝试避免反射并在枚举类中公开该方法,并让它抛出UnsupportedOperationException

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

This at least catches unintended calls during runtime - it still does not allow the compiler to catch them during compile time, but neither does the reflection approach. 这至少会在运行时捕获非预期的调用 - 它仍然不允许编译器在编译期间捕获它们,但反射方法也不会。

Because SPECIAL_VALUE is an instance of enum and enum has only method syso() .you are calling 因为SPECIAL_VALUE是实例enumenum具有唯一方法syso()您在呼唤

Here is the same thing with classes: 类与以下内容相同:

interface Foo {

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

            public void doAnonymous() {

            }
        };
        void doFoo();
    }

You cannot call method doAnonymous() like Foo.inst1.doAnonymous() and you are able to access the doAnonymous only via reflection 你不能像Foo.inst1.doAnonymous()那样调用方法doAnonymous(),你只能通过反射访问doAnonymous

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从freemarker调用带有枚举参数的方法 - How to call methods with enum parameter from freemarker 如何在Java中使用动态值调用枚举方法 - How to call enum methods with dynamic values in Java 如何在Java Singleton枚举构造函数中调用方法? - How to call methods within Java Singleton enum constructor? 如何在 hql 请求中正确调用枚举方法? numberClass 和 symbolClass 是一个枚举 - How to correctly call enum methods in an hql request ? numberClass and symbolClass is an enums Java:使用枚举在类中调用set方法 - Java: use enum to call set methods in class 如何在java中的枚举中声明单个元素? - How to declare individual elements in a enum in java? 如何调用枚举函数? - How to call enum functions? 如何将多个枚举类型作为方法参数传递,然后在它们上调用通用方法? - How to pass multiple enum types as method arguments and then call common methods on them? 当定义为泛型类参数时,如何获取枚举的 valueOf 和值并调用它实现的接口上的方法 - How to get valueOf & values of an Enum and call methods on an interface it implements when defined as a generic class param 如何将单个方法锁定在通用实用工具类中? - How to lock individual methods in a common utility class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM