【问题标题】:Enum constants implementing generic interfaces in Java在 Java 中实现泛型接口的枚举常量
【发布时间】:2012-11-03 07:27:51
【问题描述】:

假设你有一个通用接口:

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

是否可以声明一个实现MyInterface&lt;T&gt; 的枚举,但每个枚举常量都为不同的T 值实现它?也就是说,给定这个枚举:

public enum MyEnum {
    FOO,
    BAR,
    BAZ;
}

我们可以改变它,使FOO 实现MyInterface&lt;Integer&gt;BAR 实现MyInterface&lt;String&gt;,和BAZ 实现MyInterface&lt;List&lt;MyOtherType&gt;&gt;,并使MyEnum 整体实现MyInterface&lt;?&gt;?这样做似乎是完全可行的,因此它可能以类型安全的方式完成。

【问题讨论】:

    标签: java generics interface enums


    【解决方案1】:

    不,正如amalloy pointed out,Java 不允许使用类型参数声明枚举。如果您考虑使用枚举的方式,例如在switch 中,就会很清楚为什么。

    还要考虑该语言将如何实现通用枚举 - 这并非易事。对于通用枚举MyEnum&lt;T&gt;,每个枚举常量都需要将T 解析为某个特定类型,否则它们根本就不是常量。考虑一下:

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

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

    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&lt;T&gt;,您可以迭代的最具体的类型将是 MyEnum&lt;?&gt;

    【讨论】:

    • 这可能是最好的答案,并解释了为什么不可能
    【解决方案2】:

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

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

    【讨论】:

    • 使用我上面的例子,我会假设 javac 会知道诸如 MyEnum.FOO.doSomething() 之类的显式内容会返回 Integer,而上面的表达式(例如,如果 x 是传递给方法的参数)将是编译时错误,因为MyEnum 本身将实现MyInterface&lt;?&gt;,而get() 不是Object 中的方法。总而言之,这似乎与枚举常量的类型是枚举类本身的最终单例子类的概念相反。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多