虛擬機器設計團隊把類的載入階段中的」通過類的全限定名來獲取描述此類的二進位制檔案「這個操作放到虛擬機器外部去實現,以便讓程式自己去決定去實現如何載入乙個類,實現這一功能的就是「類載入器」。
對於任意乙個類,都需要由載入它的類載入器和這個類本身一同確定它在jvm中的唯一性。在比較兩個類是否相等的時候,只有這兩個這兩個類是由同乙個類載入器載入的時候才有意義,否則即使**屬於同乙個class檔案,被同乙個虛擬機器載入,仍然不會相等,這裡的相等包括物件的equals方法和isinstance方法的返回值,還包括instanceof關鍵字。
public
class test
}
輸出的結果是:
protected class<?> loadclass(string name, boolean resolve)
throws classnotfoundexception
else
} catch (classnotfoundexception e)
if (c == null)
}if (resolve)
return c;
}}
當然有時候也會遇到自定義類載入器的情況,比如需要給自己的類加密,加密過後的類肯定沒辦法用系統的類載入器進行載入,這時候就需要使用自定義的類載入器進行解密然後載入類了。還比如說一些位元組碼需要從網路上載入,就需要自定義類載入器來載入指定**的類。
下面就是乙個簡單的從本地檔案載入類的例子:
public
class
loadexternalclass
extends
classloader
@override
protected class<?> findclass(string name) throws classnotfoundexception else
}private
byte getclassdata(string classname)
return baos.tobytearray();
} catch (filenotfoundexception e) catch (ioexception e)
return
null;
}private string classnametopath(string
classname)
}
自定義類載入器的時候並不需要重寫loadclass()方法,應雙親委派邏輯已經在loadclass方法中寫明了,它首先呼叫findloadedclass()方法來檢查該類是否已經被載入過,如果沒有載入過的話,就會呼叫父類載入器的loadclass()方法來嘗試載入該類,如果父類載入器無法載入該類的話,就呼叫findclass()方法來查詢該類.所以,只需要重寫findclass()方法即可。
最後便可依在main方法中呼叫:
loadexternalclass lec = new loadexternalclass("/users/xushuzhan/desktop/blog");
testbean b = (testbean) clazz.newinstance();
b.sayhello("word");
便會輸出:
hello word
testbean中只有乙個方法:
public string sayhello(string content)
深入理解JVM 類載入器
protected class loadclass string name,boolean resolve throws classnotfoundexception else catch classnotfoundexception e if c null if resolve return c ...
類載入器載入順序
先上 public class parent static public parent public static void staticmethod1 public static void staticmethod2 測試類 public static void main string args ...
JVM 類載入機制 類載入器
類宣告週期 檔案格式驗證 基於二進位製流,只有這一步是基於二進位製流,後續步驟都是基於方法區資料 1.魔數 cafe babe 開頭 2.主次版本是否在當前jvm支援範圍 3.常量池的常量是否不被支援 4.很多很多規範 元資料驗證 1.類是否有父類,object 2.匪類是否繼承了被final修飾的...