?(1)阿里的面試官問我齿拂,可以不可以自己寫個String類
答案:不可以,因為 根據(jù)類加載的雙親委派機(jī)制肴敛,會去加載父類署海,父類發(fā)現(xiàn)沖突了String就不再加載了;
(2)能否在加載類的時候吗购,對類的字節(jié)碼進(jìn)行修改
答案:可以,使用Java探針技術(shù)砸狞,可以參考:Java探針-Java Agent技術(shù)-阿里面試題
1.什么是類加載器捻勉?
? 類加載器就是Java運行時環(huán)境(Java Runtime Environment)的一部分,負(fù)責(zé)動態(tài)加載Java類到Java虛擬機(jī)的內(nèi)存空間中刀森。恩看了這個介紹就知道了~~~原來平常的.class文件是通過這個加載器踱启,加載到內(nèi)存中的。
2.類加載器的種類以及作用
1)Bootstrap ClassLoader
負(fù)責(zé)加載$JAVA_HOME中jre/lib/rt.jar里所有的class研底,由C++實現(xiàn)埠偿,不是ClassLoader子類
2)Extension ClassLoader
負(fù)責(zé)加載java平臺中擴(kuò)展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目錄下的jar包
3)App ClassLoader(SystemClassLoader)
負(fù)責(zé)記載classpath中指定的jar包及目錄中class
4)Custom ClassLoader
屬于應(yīng)用程序根據(jù)自身需要自定義的ClassLoader榜晦,如tomcat冠蒋、jboss都會根據(jù)j2ee規(guī)范自行實現(xiàn)ClassLoader
OK那么好了,我們現(xiàn)在知道了什么是類加載器以及它的種類及作用了乾胶,那么現(xiàn)在問題來了抖剿,為什么我們自己寫的Sring類能否被加載到呢?我們自己寫一個來看看
首先胚吁,寫了一個跟JAVA自帶的String類一個一樣的String牙躺,包名也一樣就是在構(gòu)造方法里面多了一行輸出。
publicString(){
this.value =newchar[0];
System.out.println("==================");
? ? }
也就是說只要調(diào)用了我們自己寫的String類得話應(yīng)該是有輸出的腕扶,接下來我們來試試:
importjava.lang.String;
publicclassTest{
publicstaticvoidmain(String[] args){
String test =newString();
test ="測試";
?? ?System.out.println(test);
}
}
運行結(jié)果如下:
可以看到調(diào)用的是系統(tǒng)的String類孽拷,沒有輸出。
這是為什么呢半抱?查閱了一些資料終于發(fā)現(xiàn)問題所在脓恕,這就是類加載器的委托機(jī)制。
3.類加載器的委托機(jī)制
? 從JDK1.2開始窿侈,類的加載過程采用父親委托機(jī)制炼幔。這種機(jī)制能更好的保證java平臺的安全。在此委托機(jī)制中史简,除了Java虛擬機(jī)自帶的根類加載器以外乃秀,其余的類加載器都有且只有一個父加載器。當(dāng)Java程序請求加載器loader1加載Sample類時圆兵,loader1首先委托自己的父加載器去加載Sample類跺讯,若父加載器能加載,則由父加載器完成加載任務(wù)殉农,否則才由加載器loader1本身加載Sample類刀脏。
好吧~~~這下看明白了類加載器有個加載順序我們來看一下這個加載順序
加載過程中會先檢查類是否被已加載,檢查順序是自底向上超凳,從Custom ClassLoader到BootStrap ClassLoader逐層檢查愈污,只要某個classloader已加載就視為已加載此類耀态,保證此類只所有ClassLoader加載一次。而加載的順序是自頂向下暂雹,也就是說當(dāng)發(fā)現(xiàn)這個類沒有的時候會先去讓自己的父類去加載首装,父類沒有再讓兒子去加載,那么在這個例子中我們自己寫的String應(yīng)該是被Bootstrap ClassLoader加載了擎析,所以App ClassLoader就不會再去加載我們寫的String類了簿盅,導(dǎo)致我們寫的String類是沒有被加載的。