問(wèn)題背景
安卓開(kāi)發(fā)過(guò)程中,經(jīng)常要通過(guò)看一些java代碼對(duì)應(yīng)的字節(jié)碼,來(lái)了解java代碼編譯后的運(yùn)行機(jī)制,本文將通過(guò)一個(gè)簡(jiǎn)單的demo介紹一些基本的字節(jié)碼指令。
問(wèn)題分析
比如以下代碼:
public class test {
public static void main(String[] args) {
int a = 100;
int b = 100;
int c = 100;
a += b + c;
System.out.println(a);
}
}
運(yùn)行結(jié)果如下:
a += b + c <==> a += (b + c),查看對(duì)應(yīng)的字節(jié)碼文件如下:
// class version 52.0 (52)
// access flags 0x21
public class test {
// compiled from: test.java
// access flags 0x1
public <init>()V
L0
LINENUMBER 1 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this Ltest; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 3 L0
BIPUSH 100
ISTORE 1 // 將100存儲(chǔ)到局部變量
L1
LINENUMBER 4 L1
BIPUSH 100
ISTORE 2 // 將100存儲(chǔ)到局部變量
L2
LINENUMBER 5 L2
BIPUSH 100
ISTORE 3 // 將100存儲(chǔ)到局部變量
L3
LINENUMBER 6 L3
ILOAD 1 // 從局部變量表中加載 int 類(lèi)型到操作數(shù)棧
ILOAD 2 // 從局部變量表中加載 int 類(lèi)型到操作數(shù)棧
ILOAD 3 // 從局部變量表中加載 int 類(lèi)型到操作數(shù)棧
IADD // 將棧頂兩個(gè) int 類(lèi)型數(shù)值相加
IADD // 將棧頂兩個(gè) int 類(lèi)型數(shù)值相加
ISTORE 1 // 將 int 類(lèi)型存儲(chǔ)到局部變量中,這里就是把結(jié)果存儲(chǔ)到第一個(gè)變量
L4
LINENUMBER 7 L4
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ILOAD 1
INVOKEVIRTUAL java/io/PrintStream.println (I)V
L5
LINENUMBER 8 L5
RETURN
L6
LOCALVARIABLE args [Ljava/lang/String; L0 L6 0
LOCALVARIABLE a I L1 L6 1
LOCALVARIABLE b I L2 L6 2
LOCALVARIABLE c I L3 L6 3
MAXSTACK = 3
MAXLOCALS = 4
}
問(wèn)題總結(jié)
通過(guò)查看java代碼對(duì)應(yīng)的字節(jié)碼,可以比較清楚的看到j(luò)ava代碼編譯后的執(zhí)行流程。在安卓開(kāi)發(fā)中,了解字節(jié)碼知識(shí)還是非常有必要的,在關(guān)鍵時(shí)刻,我們查看字節(jié)碼,能夠很好的解答一些疑惑,下面是常見(jiàn)的一些字節(jié)碼指令:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-642601.html
1. 加載和存儲(chǔ)指令:
aload:從局部變量表中加載引用類(lèi)型到操作數(shù)棧。
astore:將引用類(lèi)型存儲(chǔ)到局部變量表中。
iload:從局部變量表中加載 int 類(lèi)型到操作數(shù)棧。
istore:將 int 類(lèi)型存儲(chǔ)到局部變量表中。
fload:從局部變量表中加載 float 類(lèi)型到操作數(shù)棧。
fstore:將 float 類(lèi)型存儲(chǔ)到局部變量表中。
2. 算術(shù)和邏輯指令:
iadd:將棧頂兩個(gè) int 類(lèi)型數(shù)值相加。
isub:將棧頂兩個(gè) int 類(lèi)型數(shù)值相減。
imul:將棧頂兩個(gè) int 類(lèi)型數(shù)值相乘。
idiv:將棧頂兩個(gè) int 類(lèi)型數(shù)值相除。
iand:將棧頂兩個(gè) int 類(lèi)型數(shù)值進(jìn)行按位與操作。
ior:將棧頂兩個(gè) int 類(lèi)型數(shù)值進(jìn)行按位或操作。
3. 類(lèi)型轉(zhuǎn)換指令:
i2l:將 int 類(lèi)型轉(zhuǎn)換為 long 類(lèi)型。
l2i:將 long 類(lèi)型轉(zhuǎn)換為 int 類(lèi)型。
f2d:將 float 類(lèi)型轉(zhuǎn)換為 double 類(lèi)型。
d2i:將 double 類(lèi)型轉(zhuǎn)換為 int 類(lèi)型。
4. 控制流指令:
if_icmpeq:如果兩個(gè) int 類(lèi)型數(shù)值相等,則跳轉(zhuǎn)到指定位置。
goto:無(wú)條件跳轉(zhuǎn)到指定位置。
tableswitch:根據(jù)索引值跳轉(zhuǎn)到不同位置的指令。
5. 方法調(diào)用和返回指令:
invokevirtual:調(diào)用實(shí)例方法。
invokestatic:調(diào)用靜態(tài)方法。
invokeinterface:調(diào)用接口方法。
ireturn:從方法中返回 int 類(lèi)型值。
invokedynamic: 運(yùn)行時(shí)動(dòng)態(tài)解析并綁定方法調(diào)用
持續(xù)更新,有興趣的小伙伴可以進(jìn)一步深入研究。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-642601.html
到了這里,關(guān)于安卓中常見(jiàn)的字節(jié)碼指令介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!