Java调用枚举的静态方法,它作为类类型变量传递而不进行强制转换

时间:2018-05-26 15:41:00

标签: java enums interface casting

我有两个枚举:

public enum Animal {
    DOG, CAT
    public static void die() {
        // ...
    }
}

public enum Plant {
    APPLE, GRASS
    public static void die() {
        // ...
    }
}

我有以下逻辑

private void startHere() {
    callMe(Animal.class);
    callMe(Plant.class);
}

private void callMe(Class<?> _class) {
    if (_class == Plant.class) {
        Plant.class.cast(_class).die(); // OK
    }

    if (_class == Animal.class) {
        Animal.class.cast(_class).die(); // ok
    }
}

如何处理_class参数并动态调用相应的die()静态方法,而不进行if比较和转换?

通常我会使用接口。问题是覆盖在Java中无法实现的接口中定义的静态方法。

2 个答案:

答案 0 :(得分:3)

你做不到。尽管名称相同,但Animal.die()Plant.die()是无关的功能。没有通用的方法来调用它们。

名称“die”表明它们应该是实例,而不是静态的方法。动物实例可能会死,是吗?不是动物类吗?如果你使它们成为实例方法,那么你可以让两个枚举实现一个公共接口:

interface Mortal {
    void die();
}

enum Animal implements Mortal { ... }
enum Plant  implements Mortal { ... }

或者,如果您确实打算将它们设为静态,则可以使用基于地图的查找替换if语句。它仍然不是编译时构造,但避免了转换。

Map<Class<?>, Runnable> killers = new HashMap<>();
killers.add(Plant .class, Plant ::die);
killers.add(Animal.class, Animal::die);

...

killers.get(_class).run();

答案 1 :(得分:0)

  

通常我会使用接口。问题是覆盖在Java中无法实现的接口中定义的静态方法。

是的,但您可以在界面中包装呼叫。使用方法引用非常简单:

private void startHere() {
    callMe(Animal::die);
    callMe(Plant::die);
}

private void callMe(Runnable m) {
    m.run();
}