首先聲明:這篇文章並不是我原創,只是感覺挺有用處,想跟大家分享一下,所以標注為原創,希望能有更多的朋友可以看到,還請原作者諒解。
昨天大D說讓我寫下DJ入門的基礎,今天寫了一大半了,結果不小心把瀏覽器給關掉了,傷心死了,本來里面請了點JAVA知道的,但是現在就不講了,下次有時間再講吧,在公司不好弄,今天就只請DJ了.
話說回來,先看圖:

其中代碼區是DJ反編譯出來的源碼,
方法列表區是在這個類里所有的方法的列表,雙擊后會在代碼區進入該方法的區域,快捷鍵區我們用不着,因為那些是把這個當作IDE才用的着的,比如寫JAVA程序啦.
下面我們請下這個怎么用,首先我們用DJ寫段小程序看看,
打開記事本,加入以下代碼
public class b {
public static void main(String args[]){
int i=5,n= Integer.parseInt(args[0]); //定義整形變量i=5,n=從命令行輸入的參數
boolean flag=i>n ? true:false; //定義boolean型變量flag.並用三目運算符計算flag的值,如果i大於n,flag值為true,如果i不大於n,flag值為false
System.out.println(flag); //輸出flag的值
}
}
保存到D盤,存為b.java
打開命令提示符,輸入d:
javac b.java
java b 8
java b 3
注意:每句都要回車
運算結果

b后面的數字是給程序傳數進去,我們的n就是讀的這個參數
下面我用用DJ反編譯b.class,這個文件和b.java在一個目錄里,當我們用javac b.java時就會生成這個文件,java b全寫應該是java b.class,但是后面的后綴可以省略,前面的.java不能省.
用UltraEdit-32打開:
不好意思,這個圖片上傳失敗了
看不懂吧,說實話,要是把這個看懂也不難,但如果里面有中文那就難懂了.
下面再用我們的DJ打開:

代碼反編譯出來后和我們原來的不一樣吧,多了一個public b(),其實這個不是多的,每個類都要有一個和自己類名相同的構造方法,只是我們沒寫而已,
下面的main函數里也和我們原來寫的不一樣了,
我們原來的int i=5變成了byte byte0 = 5; //其實這個無所謂了,因為每個我們的i值為5,用不着int型的,用byte就夠了,這是JAVA給我們優化的.
下面n的值在這里變成了i的值,這個都無所謂的,因為JAVA編譯成字節碼后算的是順序,名字無所謂.
后面的三目運算符也差不多的.輸出函數都一樣的了.那大家在想了,這樣有什么用呢,我們把他反編譯成了源碼也用不着啊,HALO里根本看不到這樣的東西,全是字節碼.
下面說到正題了,在DJ里,settings-Decompiler settings,在彈出的窗口中選中Generate JVM instructions as comments(annotete),然后點OK,再按F5刷新
如圖:

第句源碼下面的//開頭的都是上面的語句的字節碼.比如
byte byte0 = 5;
// 0 0:iconst_5
// 1 1:istore_1
源碼是byte byte0=5; 字節碼是
//0 0:iconst_5;
//1 1:istore_1;
大家看到了,這里面都是以0開始計數,但是HALO里是以1開始計數的
下圖:
所以大家在刪代碼的時候,如果DJ里是5,那么大HALO里就要5+1=6.切記.....
大家又想問,這iconst_5,istore_1是啥意思呢?
iconst_5 將int型5推送至棧頂
istore_1 將棧頂int型數值存入第二個本地變量(網上都說是第一個)
不知道為什么是第二個,而不是第一?難道也從0開始,在網上查了下都說是第一個,而我的那個JVM指令集說是第二個,不管這個了,這只是相變量索引值,看下面的代碼還能看到istore_2,istore_3之類的,這些是索引,不是真正的值.
boolean flag = byte0 > i;
// 7 9:iload_1
// 8 10:iload_2
// 9 11:icmple 18
// 10 14:iconst_1
// 11 15:goto 19
// 12 18:iconst_0
// 13 19:istore_3
這段是三目運算符的代碼,iload_1,iload_2;是取出istore_1和istore_2索引變量取出,就是上面的那個命令存進去的索引值.
然后icmple相當於if,他會拿棧頂的兩個值進行比較,就是iload_1,iload_2中的兩個值,如果小於等於0就跳轉,就是goto下面的語句,goto相當於else,這句話的意思就是,拿兩個值比較,如果iload_1中的值大於iload_2的值就往下執行icmple后的語句,然后跳過goto后面的語句,如果小於就跳過下語句,而執行goto下面的語句.大家看到icmple下面的iconst_1了吧,這句就是給int賦值為1,boolean是true,這下大家知道為什么那些XX教程里為什么留兩中都有這句了吧,知道這句goto下面的iconst_0大家應該也猜到是false了吧,
istore_3是把變量存入第3個變量(icmple和goto各一句,這句不屬於goto,不管icmple和goto執行了哪一個,都會執行這一句,這句是將判斷的值存進棧的).然后下面的
System.out.println(flag);
// 14 20:getstatic #3 <Field PrintStream System.out>
// 15 23:iload_3
// 16 24:invokevirtual #4 <Method void PrintStream.println(boolean)>
// 17 27:return
是打印語句,
getstatic 獲取指定類的靜態域,並將其值壓入棧頂
這句是裝System.out這個靜態方法取出,
iload_3將剛才存入的那個值取出來,下面的invokevirtual #4 <Method void PrintStream.println(boolean)>開始輸出指定數據類型的值,return跳出.
今天就講這么多了,要正式上班了,看我在上班時候寫的份上怎么也要頂下吧.
JVM字節碼到這里下載,是中文的,方便XX.
http://bbs.cn456.com/read-htm-tid-52033.html
