1

我的一些 Java 作业遇到了麻烦。我只是无法理解这些泛型的概念。

问题是:

假设以下是类中的方法头:

public <T implements Comparable <T>>T greatest(T arg1, T arg2)

找出错误?

我真的不明白怎么走。

4

4 回答 4

2

要使这些东西编译,您必须按以下方式修改:

public <T extends Comparable <T>> T greatest(T arg1, T arg2)

Comparable 是一个接口,但在这种情况下,extends 用于表示“扩展”(用于类)或“实现”(用于接口)。

于 2012-09-28T12:53:27.527 回答
1

错误是您不能在方法签名中使用关键字实现。仅在类声明中。这两个编译:

 public <T extends Comparable<T>>T greatest(T arg1, T arg2){
     return null;
    }

 public <T extends String>T greatest(T arg1, T arg2){
     return null;
    }
于 2012-09-28T13:02:00.127 回答
1

我非常需要对此进行解释,因为我真的不明白该怎么走。

假设您希望我们解释签名的含义...

这可以分为两部分:

public <T ...> T greatest(T arg1, T arg2)

这意味着这greatest是一个方法,它接受两个与某种类型兼容的赋值实例T,并返回一个相同类型的实例。(从名称greatest可以合理地猜测返回的值是两个参数中的较大者。)

第二部分是这样的(假设语法错误已更正):

<T extends Comparable<T>>

这意味着该类型T必须实现Comparable接口T作为其类型参数。现在,如果您查看 Comparable 的 javadocs,您会发现它只有一个方法:

public int compareTo(T other);

它被指定为比较thisother返回一个小于零、零或大于零的数字,具体取决于this(分别)是否小于、等于或大于other。(阅读 javadoc!)

所以基本上这就是说T必须是一个有compareTo方法的类。显而易见的意图是该greatest方法将使用compareTo方法来确定其 2 个参数中的哪个更大......并返回它。


至于解释语法,有两种可能的答案:

  • 语法规则就是语法规则。您只需服从它们,否则您的程序将无法编译。

  • JLS 设计者此时必须在使用implementsextends使用通用语法,或使用一些新的关键字或符号之间做出选择:

    • 添加新的关键字或符号对语言/工具链的其他部分影响太大,因此它们被“淘汰”。

    • 允许使用implementsorextends是多余的,可能会导致不必要的混淆。

    • 根据implementsorextends关键字的其他用法,(IMO)没有关于这些选择中哪个更好的令人信服的论据。如果他们基于抛硬币决定,我不会感到惊讶......

于 2012-09-28T13:02:09.800 回答
0

纠正错字后,它编译得很好。

当然,您可以使用Comparable<? super T>.

我曾经写过一个非常相似的实用方法,你可以在这里找到:

http://softsmithy.sourceforge.net/lib/current/docs/api/softsmithy-lib-core/org/softsmithy/lib/util/Comparables.html#max%28T,%20T%29

于 2012-09-28T13:00:41.773 回答