9

假设您有一个通用接口:

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<?>吗?这样做似乎是完全可行的,因此它可能以类型安全的方式完成。

4

2 回答 2

12

不,正如amalloy 指出的那样,Java 不允许使用类型参数声明枚举。如果您考虑使用枚举的方式,例如在switch.

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

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

这里有什么TFOO?该语言需要一种新的语法才能表达它,例如:

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<?>.

于 2012-11-04T00:25:06.230 回答
4

不。怎么会有人使用这样的课程?

MyEnum x = whatever;
x.foo().get(0); // how can javac know that x is the version that gives back a List?
于 2012-11-03T07:32:23.033 回答