Kotlin与Java交互问题:调用带Lambda参数的函数类型不匹配
问题原因与解决方案
这个问题我之前踩过坑,核心是Kotlin和Java在泛型协变上的默认行为差异导致的:
为什么会出现CAP#1类型错误?
Kotlin里的List<T>默认是只读且协变的(相当于List<out T>),当你从Java调用时,这个协变的List会被Java识别为List<? extends Submission>——也就是你看到的CAP#1(捕获通配符类型)。而你的Java方法updateSubmissions接受的是List<Submission>,Java的泛型是不变的,带通配符的List<? extends Submission>无法直接赋值给List<Submission>,所以编译器报错。
至于你把类转成Java后能正常调用,是因为手动写的Java类里如果用List<Submission>,它是不变的,没有协变带来的通配符问题,自然能匹配上。
几个可行的解决方案
方案1:修改Kotlin函数的参数类型(推荐)
把Kotlin函数里的List<Submission>改成**MutableList<Submission>**——因为Kotlin的MutableList<T>是不变的,对应Java里的List<Submission>,这样Java调用时类型完全匹配:
fun loadSubmissions(projectId: Long?, completion: (MutableList<Submission>, Exception) -> Unit) { ... }
方案2:在Java调用时适配类型
如果不想改动Kotlin代码,可以在Java的Lambda里把带通配符的List转成List<Submission>:
loadSubmissions(project.getProjectId(), (submissions, e) -> { // 方式1:通过新建ArrayList来消除通配符(安全但有轻微性能开销) updateSubmissions(new ArrayList<>(submissions)); // 方式2:强转(前提是你确定submissions实际类型就是List<Submission>) // updateSubmissions((List<Submission>) submissions); return null; });
方案3:修改Java的updateSubmissions方法
让Java方法接受带通配符的List,这样直接兼容Kotlin的协变List:
void updateSubmissions(List<? extends Submission> submissionList) { .. }
内容的提问来源于stack exchange,提问作者Martin Mlostek
相关产品推荐
相关产品推荐

