升级Kotlin 1.7.0出现Overload Resolution Ambiguity报错如何解决
Kotlin 1.7.0版本ical4j PropertyList重载歧义修复
错误原因
升级Kotlin到1.7.0版本后,Java互操作层的重载解析逻辑做了调整,不再对字节码中存在的同签名不同修饰符的方法做隐式选择。net.fortuna.ical4j.model.PropertyList类中同时存在两个签名完全匹配的remove方法:
- 类自身声明的final方法:
public final fun remove(p0: Property!): Boolean - 继承自集合父类的open方法:
public open fun remove(element: Property!): Boolean
两个方法入参、返回值完全一致,编译器无法判断应该调用哪一个,因此抛出Overload Resolution Ambiguity(重载解析歧义)编译错误。
触发错误的典型代码片段如下:
if (it.properties.getProperty<DtEnd>("DTEND") != null) { it.properties.remove(it.properties.getProperty<DtEnd>("DTEND")) }
可行修复方案
- 方案1:显式类型转换后调用(改动最小,无依赖要求)
PropertyList本质实现了Java的List接口,在Kotlin中映射为MutableList<Property>类型,调用remove前显式将对象转为该父类型,编译器会直接匹配父接口的remove方法,消除歧义:val targetDtEnd = it.properties.getProperty<DtEnd>("DTEND") if (targetDtEnd != null) { (it.properties as MutableList<Property>).remove(targetDtEnd) } - 方案2:封装扩展函数统一处理
如果项目中有多处同类调用,可以封装专门的扩展函数,避免重复写类型转换代码:fun PropertyList.removeTargetProperty(property: Property): Boolean { return (this as MutableList<Property>).remove(property) } // 业务调用处 val targetDtEnd = it.properties.getProperty<DtEnd>("DTEND") if (targetDtEnd != null) { it.properties.removeTargetProperty(targetDtEnd) } - 方案3:升级ical4j依赖版本
该问题本质是旧版本ical4j的字节码缺陷,类中重复声明了和父类同签名的remove方法,升级到ical4j 3.2.3及以上版本后官方已经修复该问题,无需修改业务代码即可正常编译。 - 方案4:临时回退Kotlin版本(仅应急使用)
如果短时间内无法修改代码或升级依赖,可以临时将Kotlin版本回退到1.6.x系列,旧版本解析逻辑会自动选择其中一个方法,不会抛出编译错误,但该方案只是临时规避,不建议长期使用。
内容的提问来源于stack exchange,提问作者Uriel Falak
相关产品推荐
相关产品推荐

