Kotlin递归泛型边界初始化时出现‘Type argument is not within its bounds’错误
Kotlin递归泛型边界初始化错误的修复方案
问题场景
以下代码在初始化BoundRecursively<BoundRecursively<Any>?>()时触发编译器错误:
class RawType { inner class BoundRecursively<T : BoundRecursively<T>?> fun test() { val boundRecursively = BoundRecursively<BoundRecursively<Any>?>() } }
编译器错误信息
Type argument is not within its bounds: should be subtype of 'RawType.BoundRecursively<TypeVariable(T)>?' Type argument is not within its bounds: should be subtype of 'RawType.BoundRecursively<Any>?' Type argument is not within its bounds: should be subtype of 'Any' Type argument is not within its bounds: should be subtype of 'RawType.BoundRecursively<RawType.BoundRecursively<Any>?>?' Type argument is not within its bounds: should be subtype of 'RawType.BoundRecursively<RawType.BoundRecursively<Any>?>?' Type argument is not within its bounds: should be subtype of 'RawType.BoundRecursively<Any>?'
错误原因
原泛型BoundRecursively<T : BoundRecursively<T>?>定义了递归边界约束:类型参数T必须是BoundRecursively<T>?的子类型。也就是说,T的类型需要和BoundRecursively<T>?严格兼容。当传入BoundRecursively<Any>?作为T时,需要满足BoundRecursively<Any>?是BoundRecursively<BoundRecursively<Any>?>?的子类型,这显然不成立,因此编译器抛出边界不匹配的错误。
修复方案
方案1:放宽泛型边界约束
如果不需要严格的递归类型匹配,可将泛型边界改为接受任意BoundRecursively实例的可空类型:
class RawType { // 修改泛型边界为通配符匹配 inner class BoundRecursively<T : BoundRecursively<*>?> fun test() { // 初始化可正常通过 val boundRecursively = BoundRecursively<BoundRecursively<Any>?>() } }
这种方式保留了泛型边界的基本限制,但不再要求严格的递归类型对齐,适用于大多数业务场景。
方案2:使用符合递归边界的类型参数
如果必须保留原有的递归边界设计,可传入Nothing?作为类型参数——Nothing?是所有可空类型的子类型,自然满足Nothing? : BoundRecursively<Nothing?>?的约束:
class RawType { inner class BoundRecursively<T : BoundRecursively<T>?> fun test() { val boundRecursively = BoundRecursively<Nothing?>() } }
注意:Nothing?仅能表示null,此方案仅适用于业务逻辑允许实例为null的场景。
方案3:移除递归边界约束
如果递归边界并非业务必需,可直接简化泛型定义:
class RawType { // 移除递归边界约束 inner class BoundRecursively<T> fun test() { val boundRecursively = BoundRecursively<BoundRecursively<Any>?>() } }
这种方式完全解除了类型参数的边界限制,灵活性最高,但也失去了泛型约束带来的类型安全保障。
内容的提问来源于stack exchange,提问作者Molly Tian
相关产品推荐
相关产品推荐

