这两个指令使用静态而非动态分派。看起来唯一的实质性差别在于,invokespecial
的第一个参数总是一个对象,该对象是分派方法所属类的实例。然而,invokespecial
实际上并没有将对象放在那里,编译器通过在发出 invokespecial
之前发出适当的堆栈操作序列来使其发生。因此,用 invokestatic
替换 invokespecial
不应影响运行时堆栈 / 堆的操作方式--尽管我预计它会违反规范导致 VerifyError
。
我很好奇为什么要制作两个执行本质相同的指令。我查看了 OpenJDK 解释器的源代码,似乎 invokespecial
和 invokestatic
的处理方式几乎一样。分开两个指令是否有助于 JIT 编译器更好地优化代码,或者是否有助于类文件验证器更有效地证明某些安全属性?还是这只是 JVM 设计中的怪癖?