通用边界"Enum <T>&Foo"和"Enum <?extends Foo>"之间是否存在差异?

Boh*_*ian 16 java generics

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

<T extends Enum<T> & MyInterface>
<T extends Enum<? extends MyInterface>>
Run Code Online (Sandbox Code Playgroud)

相同?


假设我有一个界面

interface MyInterface {
    void someMethod();
}
Run Code Online (Sandbox Code Playgroud)

以及一些实现它的枚举:

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

enum MyEnumB implements MyInterface {
    X, Y, Z;
    public void someMethod() {}
}
Run Code Online (Sandbox Code Playgroud)

我想要求一个实现不仅使用a MyInterface而且还使用enum."标准"方式是由一个交叉点绑定:

static class MyIntersectionClass<T extends Enum<T> & MyInterface> {
    void use(T t) {}
}
Run Code Online (Sandbox Code Playgroud)

但我发现这也有效:

static class MyWildcardClass<T extends Enum<? extends MyInterface>> {
    void use(T t) {}
}
Run Code Online (Sandbox Code Playgroud)

有了上述,这编译:

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);
}
Run Code Online (Sandbox Code Playgroud)

对于这两种情况,绑定对上面的工作和预期和要求都有效.

这两个界限之间是否存在差异,如果是这样的话,并且比另一个"更好"?

Ben*_*ulz 4

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

class MyEnumA extends Enum<MyEnum2> {}
class MyEnumB implements MyInterface {}
Run Code Online (Sandbox Code Playgroud)

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