枚举常数在Java中实现通用接口



假设您有一个通用接口:

public interface MyInterface<T> {
    T doSomething();
}

是否可以声明实现MyInterface<T>的枚举,但是每个枚举都会以T的不同值实现它的每个枚举?也就是说,给定这个枚举:

public enum MyEnum {
    FOO,
    BAR,
    BAZ;
}

我们可以更改它,以便FOO实现MyInterface<Integer>BAR实现MyInterface<String>BAZ实现MyInterface<List<MyOtherType>>,并实现MyEnum的总体实现MyInterface<?>?这样做似乎是完全可行的,因此可能以类型的方式完成。

否,正如Amalloy指出的那样,Java不允许使用类型参数声明枚举。清楚为什么您考虑要使用枚举的方式,例如在switch中。

还考虑该语言将如何实现通用枚举 - 这并不是微不足道的。对于通用枚举MyEnum<T>,每个枚举常数都需要将T解析为某种特定类型,否则它们根本不是常数。考虑一下:

enum MyEnum<T> {
    FOO; // T is not resolved
}

FOOT是什么?该语言需要一种新的语法才能表达出来,例如:

enum MyEnum<T> {
    FOO<String>;
}

因此,现在我们正在对语言提高复杂性,以支持没有过于引人入胜的用例的语义。很容易理解为什么语言设计师会简单地使用枚举的类型参数。

解决方法:

您可以通过不使用枚举来模仿所需的图案。将界面的实现组织到实用程序类中:

public class MyImplementations {
    public static final MyInterface<Integer> FOO =
            new MyInterface<Integer>() {
                ...
            };
    public static final MyInterface<String> BAR =
            new MyInterface<String>() {
                ...
            };
    public static final MyInterface<List<MyOtherType>> BAZ =
            new MyInterface<List<MyOtherType>>() {
                ...
            };
    private MyImplementations() { }
}

唯一本质上缺少的是一种迭代不同实现的方法,就像您对MyEnum.values()所做的那样 - 但是,使用假设的MyEnum<T>,您可以迭代的最特定类型是MyEnum<?>

no。有人如何使用这样的课?

MyEnum x = whatever;
x.foo().get(0); // how can javac know that x is the version that gives back a List?

最新更新