Java字节码调用接口指令

Cla*_*oft 1 java jvm

看看这个Java字节码(来自Eclipse ClassFile查看器),我发现invokeinterface指令有些奇怪:它有一个nargs(参数个数)'属性'占用2个字节:

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]
Run Code Online (Sandbox Code Playgroud)

为什么会这样?invokeinterface和之间有什么区别invokevirtual?JVM是否应该能够从给定的方法签名中推断出参数的数量(因此从堆栈中弹出的值的数量)?

yol*_*ole 7

你是对的,可以从签名中推断出参数的数量.在JVM规范,有这样一段话有关:

"invokeinterface指令的计数操作数记录参数值数量的度量,其中long或double类型的参数值为计数值提供两个单位,任何其他类型的参数贡献一个单位.此信息也可以从所选方法的描述符派生出来.冗余是历史性的."