java - 枚举如何管理泛型?

标签 java generics enums

我有一个参数化接口(interface):

public interface MyInterface<T> {
    void run(T e);
}

和实现接口(interface)的类:

public class MyClass1 implements MyInterface<SomeOtherClass1> {
    public void run(SomeOtherClass1 e) {
        // do some stuff with e
    }
}

public class MyClass2 implements MyInterface<SomeOtherClass2> {
    public void run(SomeOtherClass2 e) {
        // do some stuff with e
    }
}

不同的 MyClass*X* 的数量是已知的并且是详尽的,并且每个 MyClass*X* 只有一个实例,所以我想使用一个枚举:

public enum MyEnum {
    MY_CLASS_1,
    MY_CLASS_2;
}

能够使用MyEnum.MY_CLASS_1.run(someOtherClass1);例如(然后我会将 MyInterface 的每个实例都放在同一个地方)。甚至可能(如果是,如何)?因为我现在很困...


我尝试过的:

public enum MyEnum {

    MY_CLASS_1(new MyClass1()),
    MY_CLASS_2(new MyClass2());

    private MyInterface<?> instance;

    private MyEnum(MyInterface<?> instance) {
        this.instance = instance;
    }

    public void run(/* WhichType? */ e) {
        instance.run(e);
    }

}

在上述方法中,当使用对象类型为e时参数:

public void run(Object e) {
    instance.run(e);
    //       ^^^
    // The method run(capture#3-of ?) in the type MyInterface<capture#3-of ?> is not applicable for the arguments (Object)
}

我认为问题在于 private MyInterface<?> instance字段:我需要知道实例是如何参数化的,使用类似 private MyInterface<T> instance 的东西,但我找不到可行的解决方案...

简而言之,我卡住了 ;)


PS:自 run方法主体可能很长,我试图避免在枚举中使用匿名类:

public enum MyEnum {

    MY_CLASS_1 {
        /* any method, etc. */
    },

    MY_CLASS_2 {
        /* any method, etc. */
    },

}

MyEnum然后将变得完全不可读。

最佳答案

这是不可能的。这是我觉得最烦人的枚举限制之一,但您所能做的就是尝试解决它(就像您在 Java 5.0 之前的版本中所做的那样)。

只有枚举本身可以实现接口(interface),并且必须在枚举级别指定泛型,因此只有 Object 或这两者的一些通用接口(interface)适用于您的情况。

在枚举本身内部(并覆盖每个常量中的行为)通常是最好的解决方法。当然,您需要放宽类型安全要求。

如果您想将这些策略分开,您仍然需要在枚举中使用 run(Object) 方法,并且该方法将在每个常量中通过一些显式转换进行定义,因为您根本无法拥有不同的方法每个枚举实例的方法签名(或者即使可以,它们也不会从外部可见)。


关于如何欺骗编译器的提示,如果你真的想这样做而不是为每个实例重新设计或显式转换:

enum MyEnum implements MyInterface<Object> {
    MY_CLASS_1(new MyClass1()),
    MY_CLASS_2(new MyClass2());

    // you may also drop generics entirely: MyInterface delegate
    // and you won't need that cast in the constructor any more
    private final MyInterface<Object> delegate;

    MyEnum(MyInterface<?> delegate) {
        this.delegate = (MyInterface<Object>) delegate;
    }

    @Override
    public void run(Object e) {
        delegate.run(e);
    }
}

如果您尝试将 MyEnum.MY_CLASS_1.run()SomeOtherClass1.

关于java - 枚举如何管理泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20973221/

相关文章:

java - 或者在一段时间内语句不起作用

java - 什么是 JavaRDD[(Int, String)]?

java - 在不改变类头的情况下使用泛型

interface - 如何在 StructureMap 中注册通用接口(interface)

c++ - 解决枚举命名问题 - Qt

python-3.x - 扩展枚举并重新定义__getitem__的问题

java - 复杂 Web 应用程序上的 ConversionInputException

java - 如何通过外部网站将数据从 Activity 传递到 WebView

java - 泛型集合 "Cannot instantiate the type ArrayList<? extends OpDTO> "

java - 如何从枚举类型的属性文件中读取值?