2015-03-02 276 views
1

望着這Java字節碼(從Eclipse ClassFile的觀衆),我發現了一些奇怪與invokeinterface指令:它具有佔2個字節「屬性」一個nargs(參數個數):Java字節碼invokeinterface指令

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是否不能從給定的方法簽名中推斷參數的數量(從堆棧彈出的值的數量)?

回答

5

你說得對,參數的數量可以從簽名中推斷出來。 JVM spec有這樣的說法:

「invokeinterface指令的計數操作數記錄了一個參數值數量的度量值,其中long類型或double類型的參數值貢獻了兩個單元到計數值,而一個這個信息也可以從所選方法的描述符中得到冗餘是歷史的。「

+0

擊敗我一拳。不知道爲什麼這被包含在第一位(方法描述符已經存在於第一個JVM規範中,我確定?),似乎並不像它對原始JVM有幫助的優化。 – Voo 2015-03-02 20:55:09

+0

如果你知道在哪裏看,那麼隱藏在spec中的各種奇怪和歷史的東西。事實上,退化的領域在invokedynamic的一些早期實驗中變得派上用場 – kittylyst 2015-03-04 21:02:41