You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中Dynamic Dispatch机制疑问:为何输出3而非预期的4

Kotlin动态分发与方法调用解析

先看你的代码执行流程:

open class Shape {
    open fun number(m: Shape) = "1"
    open fun number(m: Rectangle) = "2"
}

class Rectangle : Shape() {
    override fun number(m: Shape) = "3"
    override fun number(m: Rectangle) = "4"
}

fun main() {
    val shape: Shape = Rectangle()
    println(shape.number(shape)) // 输出3而非预期的4
}

核心原因:方法调用分两步——静态选签名,动态找实现

Kotlin(和Java一致)的方法调用分为两个关键阶段:

  1. 静态绑定(编译期):编译器根据变量的静态类型(即声明时的类型,而非实际指向的对象类型)选择匹配的方法重载签名。
    • 这里变量shape的静态类型是Shape,传入参数shape时,编译器只会匹配接受Shape类型参数的number方法,也就是number(Shape)这个签名,完全不会考虑参数的实际类型是Rectangle。
  2. 动态分发(运行期):确定签名后,JVM会根据调用者的实际对象类型(此处为Rectangle),找到该类型中对应签名的重写实现。
    • 因为Rectangle重写了number(Shape)方法返回"3",所以最终调用的是这个方法,输出3。

为什么不会匹配number(Rectangle)?

重载方法的选择是编译期行为,只看静态类型。哪怕参数实际是Rectangle,但编译器看到的参数类型是Shape,就只会绑定number(Shape)的签名。如果想要调用number(Rectangle),需要让参数的静态类型为Rectangle,比如:

val rect: Rectangle = Rectangle()
println(rect.number(rect)) // 输出4

或者在运行期做类型转换:

val shape: Shape = Rectangle()
println(shape.number(shape as Rectangle)) // 输出4

内容的提问来源于stack exchange,提问作者Andrea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:18:16