16

这两个(有效的)通用界限是:

<T extends Enum<T> & MyInterface>
<T extends Enum<? extends MyInterface>>

相同?


假设我有一个界面

interface MyInterface {
    void someMethod();
}

以及一些实现它的枚举:

enum MyEnumA implements MyInterface {
    A, B, C;
    public void someMethod() {}
}

enum MyEnumB implements MyInterface {
    X, Y, Z;
    public void someMethod() {}
}

而且我想要求一个实现不仅使用aMyInterface而且它是一个枚举。“标准”方式是通过交叉路口:

static class MyIntersectionClass<T extends Enum<T> & MyInterface> {
    void use(T t) {}
}

但我发现这也有效:

static class MyWildcardClass<T extends Enum<? extends MyInterface>> {
    void use(T t) {}
}

有了上述,这编译:

public static void main(String[] args) throws Exception {
    MyIntersectionClass<MyEnumA> a = new MyIntersectionClass<MyEnumA>();
    a.use(MyEnumA.A);
    MyWildcardClass<MyEnumB> b = new MyWildcardClass<MyEnumB>();
    b.use(MyEnumB.X);
}

对于这两种情况,绑定的作品都符合上述预期和要求。

这两个界限之间是否有区别,如果有,那又是什么,一个比另一个“更好”吗?

4

4 回答 4

4

在这种特定情况下,没有区别,因为 Enums 形式类型参数实际上是 self 类型。这是因为不能像这样从 Enum 继承:

class MyEnumA extends Enum<MyEnum2> {}
class MyEnumB implements MyInterface {}

所以是的,从语义上讲,它们是相同的界限,但仅仅是因为它是枚举。

于 2013-01-02T13:25:34.320 回答
3

正如其他人所指出的那样,两种语法都实现了相同的界限 - 只是因为枚举的特殊情况,我们知道TinEnum<T>必须是立即扩展enum类型。因此,在限制T可以解决的问题方面,没有区别。

的实例的可能用法有所不同,但这可能是一个无关紧要的细微差别T考虑以下语句编译MyIntersectionClass.use但不是MyWildcardClass.use

T t2 = t.getDeclaringClass().newInstance();

只有这些将在后者中编译:

MyInterface t2 = t.getDeclaringClass().newInstance();
Enum<? extends MyInterface> t3 = t.getDeclaringClass().newInstance();
于 2013-01-02T17:48:55.190 回答
2

由于第二个依赖于 Java 枚举实现为的特殊事实,因此MyEnum extends Enum<MyEnum>我更喜欢第一个,它不依赖此类假设并明确说明您的约束。

于 2013-01-02T13:23:17.907 回答
1

他们会做同样的事情,但我想说T extends Enum<? extends MyInterface>的是更标准一点,因此更好,如果只是因为它更普遍和更容易识别。许多人甚至不知道&泛型的部分。

您也可以争辩说它们的阅读方式略有不同。T extends Enum<T> & MyInterface我会读作“一个恰好也是 MyInterface 的枚举”。T extends Enum<? extends MyInterface>我会读作“实现 MyInterface 的枚举”。所以在这个程度上,这是个人喜好的问题;我更喜欢后者。

于 2013-01-02T13:22:52.183 回答