【问题标题】:Java Bytecode invokeinterface instructionJava 字节码调用接口指令
【发布时间】:2015-05-03 08:27:45
【问题描述】:

查看这个 Java 字节码(来自 Eclipse 类文件查看器),我注意到 invokeinterface 指令有些奇怪:它有一个占用 2 个字节的 nargs(参数数量)“属性”:

35  aload_2 [map]
36  ldc <String "a"> [15]
38  invokeinterface java.util.Map.get(java.lang.Object) : java.lang.Object [33] [nargs: 2]
43  checkcast java.lang.String [35]
46  invokevirtual java.io.PrintStream.println(java.lang.Object) : void [47]
49  getstatic java.lang.System.out : java.io.PrintStream [41]

为什么会这样? invokeinterfaceinvokevirtual 有什么区别? JVM 不应该能够从给定的方法签名中推断出参数的数量(从而从堆栈中弹出的值的数量)吗?

【问题讨论】:

    标签: java jvm


    【解决方案1】:

    您是对的,可以从签名中推断出参数的数量。 JVM spec 对此有话要说:

    “invokeinterface 指令的计数操作数记录了参数值数量的度量,其中 long 类型或 double 类型的参数值对计数值贡献两个单位,任何其他类型的参数贡献一个单位。这信息也可以从所选方法的描述符中得出。冗余是历史的。"

    【讨论】:

    • 打我一拳。不知道为什么首先包含它(我确定第一个 JVM 规范中已经存在方法描述符?),甚至看起来对原始 JVM 没有帮助。
    • 如果你知道在哪里看的话,规范中隐藏着各种奇怪的和历史的东西。碰巧的是,残留场在一些早期的 invokedynamic 实验中派上用场
    猜你喜欢
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 2020-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多