【发布时间】:2013-08-31 22:49:57
【问题描述】:
这是 Java 中的一个著名习语。参见例如this SO discussion。所以基本上要定义一个接口,实现它的类需要有一个方法来与其类的对象进行比较:
public interface IComparable<T extends IComparable<T>> {
public int compare(T item);
}
(注意:这显然是解决特定用例的一种不必要的复杂方法 - 请参阅this post - ,但我正在询问如何解释递归语法,更不用说特定的应用程序了)。
简而言之,这是一个递归定义,没有明显的递归结束,我看不出编译器/类型系统如何实现这一点。
此外,尝试用语言表达(“IComparable 是一个类,其实例可以与实现 IComparable 接口的类的对象进行比较”)会产生一个不合逻辑的循环定义,而这在哲学/逻辑/数学中是不可能的但显然在编译器设计中是可行的(!)。
此外,如果原始习语语法是可以接受的,那么似乎也可以说:
public interface IComparable<T extends IComparable<T extends IComparable<T>>> {
public int compare(T item);
}
...但编译器显然只允许一级extend。
谁能帮我理解这种递归泛型定义?
更新
根据接受的答案 (BartoszKP),我认为我现在理解的是以下内容:
“递归”定义不应被解读为(代表“定义依赖于”关系的箭头):
[ IComparable<T> ] -------> [ IComparable<T> ]
...这是不合逻辑的(循环),而是:
[ IComparable<T> ] ----------> [ list of methods (parameterized by T) ]
\ ^
\ |
\-------> [ type bound on T ]-------/
... 这不是不合逻辑的,因此在编译器中是可行的。因此,换句话说,IComparable 的定义是根据它定义的方法列表和它在类型 T 上定义的边界给出的,而后者又取决于方法列表。所以,没有递归。
【问题讨论】:
-
我不明白你为什么认为这是 recursive 或 circular... 阅读 OldCurmudgeon 的答案,它清楚地解释了它的原因不是。
-
您的第二个代码示例混淆了
T的声明和使用。不幸的是,C 行语法故意使两者看起来相似。 -
"这是 Java 中众所周知的成语。"它并不为人所知。而且没用。