接口扩展与泛型报错:类型实参不在限定范围内
Kotlin泛型约束报错分析与解决
场景与问题
给定不可修改的库代码:
interface A<T> { fun get(): T } abstract class C<T: A<K>, K: Any> class AImpl : A<AImpl> { override fun get() = this } class CImplA : C<AImpl, AImpl>() // 可正常实例化
为避免每个实现A<X>的类都重复重写get()方法,创建了接口B:
interface B : A<B> { override fun get() = this }
但实现BImpl并尝试创建CImplB时,编译器报错:
class BImpl : B class CImplB : C<BImpl, BImpl>() // ^^^^^ -> Type argument is not within its bounds. // Expected: A<BImpl> // Found: BImpl
原因分析
这是泛型类型匹配的写法问题,既不是编译器限制也不是类型擦除导致的:
- 接口B的声明是
B : A<B>,意味着B实现的是A<B>,而非A<X>(X为B的子类)。 - 当BImpl继承B时,BImpl实际实现的是
A<B>,但C的泛型约束要求第一个参数T必须是A<K>(此处K为BImpl),即需要T是A<BImpl>,两者类型不匹配,因此触发报错。
解决方法
将B改为递归泛型接口,让子类指定自身作为类型参数,从而自动满足A<X>的约束:
interface B<X : B<X>> : A<X> { override fun get(): X = this as X }
然后按如下方式实现BImpl和CImplB:
class BImpl : B<BImpl> class CImplB : C<BImpl, BImpl>() // 编译正常
这种递归泛型是Kotlin中实现"自类型"约束的常用模式,this as X是安全的——因为X就是子类本身,运行时实例必然是X类型。
内容的提问来源于stack exchange,提问作者Alessandro Vezzoli
相关产品推荐
相关产品推荐

