为何实现Comparable接口的类不满足泛型Comparable<T>约束?
问题原因与解决方案
核心本质
你遇到的是Java泛型中自限定类型约束的问题:T extends Comparable<T>要求泛型参数T必须实现Comparable<T>(即能和自身类型比较),而不是和它的父接口/父类比较。
通用示例问题分析
看你的通用代码:
- 接口
A继承Comparable<A>,意味着A的实现类需要能和A类型比较; - 类
B实现A后,compareTo的参数是A,而不是B——这说明B只能和A(或其子类)比较,无法保证能和B自身比较,因此不满足Comparable<B>的约束,自然无法作为C<T extends Comparable<T>>的泛型参数。
你的代码问题分析
对应到你的实际代码:
KeyListInterface<T>继承Comparable<KeyListInterface<T>>,所以它的实现类需要能和KeyListInterface<T>类型比较;MovieList<T>实现KeyListInterface<T>后,compareTo的参数是KeyListInterface<T>,不是MovieList<T>——这意味着MovieList<T>并没有实现Comparable<MovieList<T>>,不符合RedBlackTree<T extends Comparable<T>>的约束要求。
两种解决方案
方案1:修改接口,使用自限定泛型
让接口的泛型参数指向自身类型,确保实现类必须和自身比较:
通用示例修改后代码
// 修改接口A为自限定泛型 public interface A<T extends A<T>> extends Comparable<T> { } // B实现A<B>,此时compareTo的参数是B public class B implements A<B> { @Override public int compareTo(B o) { return 0; } } // C的约束不变 public class C<T extends Comparable<T>> { public int data; } // 此时C<B>可以正常实例化 public class Main { public static void main(String[] args) { C<B> test = new C<B>(); } }
你的代码修改后
调整KeyListInterface的泛型声明,添加自限定参数:
public interface KeyListInterface<T extends Comparable<T>, U extends KeyListInterface<T, U>> extends Comparable<U>, Iterable<T> { void addKey(T newKey); boolean containsKey(T key); }
然后让MovieList实现KeyListInterface<T, MovieList<T>>:
import java.util.Iterator; public class MovieList<T extends Comparable<T>> implements KeyListInterface<T, MovieList<T>> { @Override public void addKey(T newKey) {} @Override public boolean containsKey(T key) { return false; } // 此时compareTo的参数是MovieList<T>,满足Comparable<MovieList<T>> @Override public int compareTo(MovieList<T> o) { return 0; } @Override public Iterator<T> iterator() { return null; } }
最后RedBlackTree的约束不变,RedBlackTree<MovieList<SomeType>>就能正常实例化了。
方案2:放宽泛型类的约束
如果不想修改接口,可以把RedBlackTree(以及通用示例中的C)的泛型约束从T extends Comparable<T>改为T extends Comparable<? super T>:
// 修改RedBlackTree的泛型约束 public class RedBlackTree<T extends Comparable<? super T>> extends BinarySearchTree<T> { // ... 原有代码 }
这个约束的意思是:T只要能和它的父类型比较即可。因为MovieList<T>实现了Comparable<KeyListInterface<T>>,而KeyListInterface<T>是MovieList<T>的父接口,所以Comparable<? super MovieList<T>>包含了Comparable<KeyListInterface<T>>,满足约束条件。
内容的提问来源于stack exchange,提问作者Daybreak Texas
相关产品推荐
相关产品推荐

