【问题标题】:Is there a difference between the generic bounds "Enum<T> & Foo" and "Enum<? extends Foo>"通用边界“Enum<T> & Foo”和“Enum<? extends Foo>”之间有区别吗
【发布时间】:2013-06-26 04:22:11
【问题描述】:

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

<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() {}
}

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

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);
}

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

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

【问题讨论】:

  • 如果他们真的很理智,我更喜欢交集,因为它不使用通配符,我个人认为它“不干净”

标签: java generics


【解决方案1】:

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

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

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

【讨论】:

  • +1 用于回答问题的建设性部分,而不是将时间浪费在“更好”的语法是什么上,因为它们的含义相同。
【解决方案2】:

正如其他人所指出的,这两种语法都达到了相同的界限——而且仅仅是因为枚举的特殊情况,我们知道Enum&lt;T&gt; 中的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();

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      他们会做同样的事情,但我会说T extends Enum&lt;? extends MyInterface&gt; 更标准一点,因此更好,如果只是因为它更常见且更容易识别。很多人甚至不知道泛型的&amp; 部分。

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

      【讨论】:

      • -1 抱歉,第一个子句之后的所有内容都是主观的,没有建设性。
      • @PaulBellora OP 的问题包括问题and is one "better" than the other。这本质上是一个主观问题,因此让人们回答这个问题似乎是不公平的。你的反对票当然是你来分发的,但我认为你的推理使 SO suggestions for downvotes 紧张,因为它不是很明显或者可能是危险的不正确,我认为它也不是草率或不努力扩展的。
      • 这是我第一次对你投反对票,我保证我考虑过。不要个人认为:)
      • 我不是,别担心。 :) 2 分也不会毁了我的新年。我猜,对于 SO 的用途存在不同意见。
      猜你喜欢
      • 1970-01-01
      • 2016-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2012-08-08
      • 2016-12-01
      • 2017-07-04
      相关资源
      最近更新 更多