在签名中的表达式<T extends Comparable<T>>中,例如
public static <T extends Comparable<T>> foo(T x) { ... }T的描述递归地依赖于Comparable<T>。
如果T扩展了Comparable<T>,Comparable<T>扩展了Comparable<Comparable<T>>,那么T不就是扩展了Comparable<Comparable<T>>吗
那么,extends关系是可传递的吗?
如果是这样,为什么不是
public static <T extends Comparable<Comparable<T>>> int compare(T x, T y) {
return x.compareTo(y);
}等同于
public static <T extends Comparable<T>> int compare(T x, T y) {
return x.compareTo(y);
}?实际上,最后一个定义可以编译,而它上面的定义则无法编译,错误如下
comp.java:7: compareTo(java.lang.Comparable<T>) in
java.lang.Comparable<java.lang.Comparable<T>> cannot be applied to (T)
return x.compareTo(y);谢谢!
发布于 2011-08-05 08:06:44
要记住的基本问题是Java泛型是由编译单元和编译时限定范围的。这只是语法上的糖!(有多少次我忘记了这一点,最后完全按照您所做的方式进行推理,就好像Java泛型实际上暗示了运行时的泛型类型系统一样。)
来自the spec
The scope of a class' type parameter is the entire declaration of the class
including the type parameter section itself.
Therefore, type parameters can appear as parts of their own bounds, or as
bounds of other type parameters declared in the same section.没有递归,也没有定义新的类型。
也就是说:
package so_6949760;
import java.util.HashMap;
public class SweetCompilingGenerics {
@SuppressWarnings("serial")
public static class Sweet<X> extends HashMap<X, Sweet<X>> {}
public static void main(String[] args) {
Sweet<String> sweetStr = new Sweet<String>();
Sweet<Sweet<Integer>> whatever = new Sweet<SweetCompilingGenerics.Sweet<Integer>>();
assert sweetStr.getClass().equals(whatever.getClass()) : "who made generics a runtime mechanism?";
assert sweetStr.getClass() == whatever.getClass() : "who made generics a runtime mechanism?";
System.out.format("Is %s a Sweet<String> ?\n", sweetStr.getClass().getCanonicalName());
System.out.format("Is %s a Sweet<Sweet<Integer>> ?\n", whatever.getClass().getCanonicalName());
}
}将输出甜蜜的秘密:
Is so_6949760.SweetCompilingGenerics.Sweet a Sweet<String> ?
Is so_6949760.SweetCompilingGenerics.Sweet a Sweet<Sweet<Integer>> ?我可以如此期待地给另一位极客朋友提个建议吗?请务必阅读规范。
post accept edit:刚找到这个highly informative article by IBM。这基本上解决了OP的所有问题。(推荐)。
发布于 2011-08-05 07:34:02
我认为你在这里做了一个不正确的逻辑跳跃。
T extends Comparable<T>不是在暗示吗
Comparable<T> extends Comparable<Comparable<T>>短类比
假设碎石机是任何可以粉碎岩石的材料,而岩石恰好能够自我破碎。因此,rock是一个碎石机。这是否意味着岩石可以粉碎任何可以粉碎岩石的物质?显然不是:钢可能也是一种碎石机,而石头可能不会压碎钢。
Long (基于代码)类比
假设我有一个接口Additive<T>,它可以用来描述任何类型,您可以在T对象上对这些类型执行add操作,然后返回一个T。
现在假设我有一些方法,其签名如下所示:
public static <T extends Additive<T>> add(T x, T y) { ... }因为x必须是我可以添加T的类型,所以这个方法可以按如下方式实现:
return x.add(y);讲得通?好的,很好;但现在让我们假设您在问题中所做的假设:Additive<T>必须扩展Additive<Additive<T>>;如果是这样的话,我可以假设我可以向x添加一个实现Additive<T>的任何类型的实例。
这就是假设被打破的地方。我可能有一种类型,比如说...
// A 32-bit integral number supporting addition
public class Int32 implements Additive<Int32> { ... }这是有道理的,对吧?我也可以有这样的东西:
// A list of 32-bit integral numbers supporting appending
public class Int32List implements Additive<Int32> { ... }现在,如果T extends Additive<T>暗示Additive<T> extends Additive<Additive<T>>,那么我应该能够这样做:
Additive<Int32> x = new Int32(5);
Additive<Int32> y = x.add(new Int32List());这有什么意义吗?
发布于 2011-08-05 07:29:35
没有什么特别之处
<T extends Comparable<T>>考虑一下
public class Foo implements Comparable<Foo>{
int compareTo(Foo x);
}我甚至不认为我们可以说它是递归定义的,它只是自引用。
https://stackoverflow.com/questions/6949760
复制相似问题