手寫Java虛擬機(三)—— 解析class類文件

唔。。在解析前,先給大家介紹下Class類文件結構吧。

Class文件格式採用的是一種類似C語言結構體的僞結構來存儲數據,這種僞結構中只有兩種類型:無符號數和表。

無符號數屬於基本的數據類型,用u1,u2,u4,u8來代表1個字節,2個字節,4個字節,8個字節的無符號數,可以用來描述數字、索引、數量值等。

表是由多個無符號數或者其他表作爲數據構成的複合數據類型,所有表都習慣性以“_infor”結尾,整個Class文件本質上就是一張表。

下面是Class文件的結構。

 Class文件就是嚴格按照這個格式來存儲數據的。

唔。。多說無益,直接上例子吧。

public class tt {
    private int m;

    public int inc() {
        return m + 1;
    }
}

這個我們tt.java的代碼,下面,我們就要把這個tt.java編譯後的tt.class文件,給解析出來。

首先,javac 命令tt.java編譯成tt.class

然後,用16進制查看器查看tt.class文件

這就是class文件了,下面我們按照上面的class文件結構來一步一步分析。

1.magic魔數和minor_version、major_version。

每個class文件的頭4個字節稱爲魔數,它的唯一作用就是確定這個文件是能被jvm解析的class文件。很多不同格式的文件都是通過魔數來進行識別的,比如gif或者jpeg等文件頭中都有魔數。

class文件的魔數是固定的值爲:0xCAFEBABA,這和我們class文件結構圖中的描述一致,是u4類型的數據。

之後是Class文件的版本號,minor_version是次版本號,值爲0x0000,major_version是主版本號,值分別是0x0034,也就是十進制的52,也就是JDK1.8版本編譯的。

下面是Class文件版本號

2.常量池

接着版本號之後的是常量池:constant_pool_count,constant_pool。

constant_pool_count代表的是常量池的數量,這個數量的計數是從1開始,而不是0開始的。

在該例子中,常量池數量爲十六進制數0x0013,即十進制的19,因爲計數是從1開始,所以,這常量池的數量爲19-1=18。

跟在常量池數量之後的是具體的常量池內容。常量池中主要存放兩大類常量:字面量和符號引用,字面量也就是字符串、final類型的常量值等,符號引用則是編譯方面的概念。

在JDK1.7之前一共有11種結構各不相同的表結構。這些表都有一個共同特點,第一位是u1類型的標誌位,用來標緻是哪種類型的常量。下面是標誌相對應的常量類型。

詳細的常量類型結構我這裏就不寫了,這裏只寫例子中所用到的類型結構。建議大家參考《深入理解java虛擬機》第6章。

唔。。。。

寫到這裏突然不想寫了,因爲class類文件結構不難,同時,覺得自己這篇博客寫的沒什麼實際意義。

第一,寫給自己做總結吧,也沒總結到啥,因爲真的不難,沒啥好總結的感覺,

第二,寫給大家看吧,大家還不如看書,書裏講的很詳細,要是有不懂的,可以留言交流。

唔。。

也可以參考我寫的解析代碼:https://github.com/ZheBigFish/myjvm,ch03寫的就是類文件解析

唔,建議大家多看書。

最後,本文參考自《深入理解java虛擬機》第6章。

OK,此貼終結。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章