带有泛型where约束的Kotlin扩展函数Java编译失败如何解决
问题原因
该错误是Kotlin 1.4.x~1.5.x版本区间的编译器bug导致的:当扩展函数存在多个泛型上界约束时,Kotlin编译器生成Java方法签名时,泛型边界的闭合符号>和返回值类型之间缺少空格,会生成<T extends androidx.fragment.app.Fragment & FragmentPresentable>void这样不符合Java语法的签名(正确格式要求>和返回值之间必须有空格),Java编译器识别该签名时就会抛出你遇到的语法错误。如果项目启用了KAPT注解处理工具,该问题会更容易被触发。
修复方案
- 方案1(优先推荐):如果该扩展函数仅在Kotlin代码中调用,给函数添加
@JvmSynthetic注解,该注解会让方法仅对Kotlin可见,不会生成Java可调用的方法签名,从根源避免该问题:
@JvmSynthetic fun <T> T.showAppPresentation( appPresentable: Maybe<AppPresentable>, appPresentationView: AppPresentationView, closeListener: () -> Unit ) where T : Fragment, T : FragmentPresentable { TODO() }
- 方案2:升级Kotlin插件及编译器版本到1.6.0及以上,官方已经在该版本修复了泛型签名生成的bug,升级后重新编译即可解决。
- 方案3:如果需要兼容Java调用且暂时无法升级Kotlin版本,可以调整函数定义,将编译期泛型约束移到运行期校验:
fun Fragment.showAppPresentation( appPresentable: Maybe<AppPresentable>, appPresentationView: AppPresentationView, closeListener: () -> Unit ) { require(this is FragmentPresentable) { "调用该方法的Fragment必须实现FragmentPresentable接口" } TODO() }
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

