深入理解JAVA虛擬機學習筆記14——類加載的驗證過程

每天進步一點點!

上一篇已經學習了加載階段,這一篇我們瞭解一下驗證的過程。

我們已經知道了,虛擬機加載的是Class字節碼文件,我們也通過工具查看了文件中存儲的是二進制流。

下面我們打開一個文件AppTest.class,我們在文件的開頭隨便加入一個字母“f”,如下圖所示。

那麼,我們通過命令行輸入命令“java AppTest”,會出現什麼結果呢?

虛擬機會報一個Class文件格式化錯誤,這是我們隨便修改的一個,但是如果某些別有用心的人,惡意修改了class文件,爲了避免對虛擬機造成傷害,虛擬機必須要在確保Class文件的內容符合虛擬機的要求規範。

驗證部分主要包含下面四個階段的驗證:

1. 文件格式的驗證:驗證文件格式是否按照虛擬機的規範,也就是我們前面class文件結構中的內容,比如這是不是一個Class文件(看魔數,是否位CAFEBABE);Java版本是否符合當前虛擬機的範圍(Java可以向下兼容,但是不能處理大於當前版本的程序)等等。

2. 元數據的驗證:對Class文件中的元數據進行驗證,是否存在不符合Java語義的元數據信息。

這裏有的朋友可能會比較疑惑,什麼是元數據呢?一般情況下,一個文件中都數據和元數據。數據指的是實際數據,而元數據(Metadata)是用來描述數據的數據。用過Java註解的朋友應該對元數據這種叫法並不陌生,對應的元註解,其實說的差不多都是一個意思。

舉個例子:比如說我們定義了一個變量 int a = 1;可以理解成數據就是1,而元數據就是描述有一個字符串變量“a”,這個“a”的類型是int型的,它的值也是一個int型的1,這就是描述數據的數據,就是元數據。

3. 字節碼的驗證:通過數據流和控制流分析,來確定程序語義是否合法。

以數據來說,要保證類型轉換是有效的;對於控制流程的代碼,不能讓指令跳轉到其它方法的字節碼指令上等……

4. 符號引用的驗證:爲了保證解析動作能正常完成,還需在虛擬機將符號引用轉成直接引用的時候,判斷其它要引用的類是否符合規定。比如,要引用的類是否能夠被找到;引用的屬性在對應類中是否存在,權限是否符合要求(private的是不能訪問的)等。

最後再說一點,驗證階段不是必須的,如果代碼運行已經穩定了之後,可以通過設置參數-Xverfy:none參數來關閉類驗證,減少虛擬機的類加載時間,提高運行效率。

既然說到了驗證,不知道朋友們有沒有想到另一個問題,那就是混淆。

有很多時候,爲了使我們的代碼不被反編譯出來,我們會對程序的關鍵部分進行加密處理,讓文件不容易被反編譯出來,混淆技術應用而生。

這裏就簡單的給朋友們介紹一個工具——ProGuard,想要使用的朋友可以自行搜索查看,這裏需要注意的是,混淆工具並不是百分百好用,有些涉及到反射的類是不能使用混淆工具的,否則會出現問題。

喜歡文章或想一起學習的朋友可以關注我,給我點贊,我將會持續更新,有什麼疑問或文中有不當之處請給我留言,真誠地希望能與大家一起交流探討,學習進步。


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