当委托对象是重写(对于 final 和 sealed 类的情况)或可能重写(对于 open 和 abstract 类的情况)Java 默认方法的类的实例时,报告委托。
根据设计,Kotlin 委托不会覆盖 Java 默认方法,这可能导致难以捉摸的错误,尤其是在继承层次结构很深的情况下。
示例:
// Base.java:
public interface Base {
default void print() {
System.out.println("Base");
}
}
// BaseImpl.kt:
class BaseImpl : Base {
override fun print() {
println("BaseImpl")
}
}
// Main.kt:
fun main() {
val inherited = BaseImpl()
val delegated = object : Base by inherited {}
inherited.print() // Outputs: BaseImpl
delegated.print() // Outputs: Base
}
开发者通常期望所有方法,包括在委托中重写的默认方法,都被转发。 相反,调用的是 Java 默认方法,这可能会导致意外的结果。
一种快速修复是通过将 Java 默认方法的实现委托给委托对象来重写这些方法。
// Main.kt:
fun main() {
val inherited = BaseImpl()
val delegated = object : Base by inherited {
override fun print() {
inherited.print()
}
}
inherited.print() // 输出: BaseImpl
delegated.print() // 输出: BaseImpl
}
另一种快速修复是通过显式地将 Java 默认方法的实现委托给超类来重写这些方法。
// Main.kt:
fun main() {
val inherited = BaseImpl()
val delegated = object : Base by inherited {
override fun print() {
super.print()
}
}
inherited.print() // Outputs: BaseImpl
delegated.print() // Outputs: Base
}
2025.1 的新功能