【问题标题】:Using a Generic Class as Upper Bound of a Type Parameter使用泛型类作为类型参数的上限
【发布时间】:2019-12-12 10:47:13
【问题描述】:

我正在为 Java 中类型参数的泛型界限而苦苦挣扎。我想要达到的目标如下:

  • 我有一个泛型类(示例代码中的Generic<> (1))
  • 我有一个泛型类,其中类型参数的范围应覆盖第一个泛型类的类型(UsingGeneric<> (2);这已经很奇怪了,因为它迫使我重复 Comparable 约束)
  • 然后我想用第三个类 (MyGeneric (3)) 实例化第二个类,它扩展了第一个类的具体应用程序。

可以这样想:您有一个通用容器类,其中的元素受到约束。你有一个泛型迭代器类,它作用于这些容器。现在你想为一个具体的容器创建一个具体的迭代器。

问题:语句(4)无法编译,抱怨: Type parameter MyGeneric is not within its bound; should extend Generic<MyGeneric>.

问题似乎是 Java 迫使我在上限中重复类型变量 - 这有点荒谬,因为在容器示例中,我不希望我的具体容器属于“容器的容器”。我仍然希望它是“可比较的容器”类型。即UsingGeneric 类应该有一个签名,其中主类型变量与上限的类型变量解耦,有点像UsingGeneric<T extends Generic<S> & Comparable<S>>。这是不可能的,AFAIK。

我做错了什么?

示例代码:

class Test {

  static class Generic<E extends Comparable<E>> {}  // (1)

  static class UsingGeneric<T extends Generic<T> & Comparable<T>> {} // (2)

  static class MyGeneric extends Generic<Integer> {}  // (3)

  static UsingGeneric<MyGeneric> myUsingGeneric;  // (4) - won't compile

}

【问题讨论】:

  • 嗯,一个问题是MyGeneric extends Generic&lt;Integer&gt; 将泛型类型定义为IntegerUsingGeneric&lt;T extends Generic&lt;T&gt; &amp; Comparable&lt;T&gt; 要求它 扩展或实现Generic&lt;T&gt; 其中@987654333 @ 显然不行。
  • 你需要类似:UsingGeneric&lt;T extends Generic&lt;E&gt;, E extends Comparable&lt;E&gt;&gt;
  • @Slaw 这看起来很棒。它只是迫使我有第二个类型参数UsingGeneric&lt;MyGeneric,Integer&gt; myUsingGeneric,这有点多余但可以编译。考虑根据您的评论做出回答。

标签: java generics


【解决方案1】:

您当前的代码无法编译的原因是:

class UsingGeneric<T extends Generic<T> & Comparable<T>> { ... }

要求使用的类型参数必须同时实现Generic&lt;T&gt;Comparable&lt;T&gt;Integer 类可能实现了后者但没有实现前者,因此编译错误。您必须再次指定Comparable 边界的原因是UsingGeneric 声明了一个 类型参数T,它被用作类型参数Generic 绑定,这是此上下文中的参数化类型。由于Generic 的类型参数以Comparable 为边界,因此您必须确保UsingGeneric 的类型参数具有兼容的边界。

也就是说,您似乎正在寻找一种方法来指定使用的Comparable 类型 Generic 类型,而不要求该类型实现两个接口。这将需要两个类型参数:

class UsingGeneric<T extends Generic<E>, E extends Comparable<E>> { ... }

起初这似乎是多余的,但所有信息都是必要的。现在我们将E 用作TGeneric 边界的类型参数,同时允许E 是与T 不同的类型。但同样,由于Generic 的类型参数由Comparable 界定,我们必须确保E 具有兼容的界限。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多