大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

第一部分 Java基礎
第二部分 Java進階

Java類加載器面試題

1、Java的類加載器的種類都有哪些?

● 根類加載器(Bootstrap)--C++寫的,看不到源碼;

● 擴展類加載器(Extension)--加載位置:jre\lib\ext中;

● 系統(應用)類加載器(System\App) --加載位置:classpath中;

● 自定義加載器(必須繼承ClassLoader)。

2、類什么時候被初始化?

● 創建類的實例,也就是new一個對象

● 訪問某個類或接口的靜態變量,或者對該靜態變量賦值

● 調用類的靜態方法

● 反射(Class.forName("com.lyj.load"))

● 初始化一個類的子類(會首先初始化子類的父類)

● JVM啟動時標明的啟動類,即文件名和類名相同的那個類只有這6中情況才會導致類的類的初始化。

● 類的初始化步驟:

如果這個類還沒有被加載和鏈接,那先進行加載和鏈接;

假如這個類存在直接父類,并且這個類還沒有被初始化(注意:在一個類加載器中,類只能初始化一次),那就初始化直接的父類(不適用于接口);

加入類中存在初始化語句(如static變量和static塊),那就依次執行這些初始化語句。

3、Java類加載體系之ClassLoader雙親委托機制

java是一種類型安全的語言,它有四類稱為安全沙箱機制的安全機制來保證語言的安全性,這四類安全沙箱分別是:

1.類加載體系

2.class文件檢驗器

3.內置于Java虛擬機(及語言)的安全特性

4.安全管理器及Java API

● 主要講解類的加載體系:

java程序中的.java文件編譯完會生成.class文件,而.class文件就是通過被稱為類加載器的ClassLoader加載的,而ClassLoder在加載過程中會使用“雙親委派機制”來加載.class文件,圖:

BootStrapClassLoader:啟動類加載器,該ClassLoader是jvm在啟動時創建的,用于加載$JAVA_HOME$/jre/lib下面的類庫(或者通過參數-Xbootclasspath指定)。由于啟動類加載器涉及到虛擬機本地實現細節,開發者無法直接獲取到啟動類加載器的引用,所以不能直接通過引用進行操作。

ExtClassLoader:擴展類加載器,該ClassLoader是在sun.misc.Launcher里作為一個內部類ExtClassLoader定義的(即sun.misc.Launcher$ExtClassLoader),ExtClassLoader會加載$JAVA_HOME/jre/lib/ext下的類庫(或者通過參數-Djava.ext.dirs指定)。

AppClassLoader:應用程序類加載器,該ClassLoader同樣是在sun.misc.Launcher里作為一個內部類,AppClassLoader定義的(即sun.misc.Launcher$AppClassLoader),AppClassLoader會加載java環境變量CLASSPATH所指定的路徑下的類庫,而CLASSPATH所指定的路徑可以通過System.getProperty("java.class.path")獲取;當然,該變量也可以覆蓋,可以使用參數-cp,例如:java-cp路徑(可以指定要執行的class目錄)。

CustomClassLoader:自定義類加載器,該ClassLoader是指我們自定義的ClassLoader,比如tomcat的StandardClassLoader屬于這一類;當然,大部分情況下使用AppClassLoader就足夠了。

前面談到了ClassLoader的幾類加載器,而ClassLoader使用雙親委派機制來加載class文件的。ClassLoader的雙親委派機制是這樣的(這里先忽略掉自定義類加載器CustomClassLoader):

1.當AppClassLoader加載一個class時,它首先不會自己去嘗試加載這個類,而是把類加載請求委派給父類加載器ExtClassLoader去完成。

2.當ExtClassLoader加載一個class時,它首先也不會自己去嘗試加載這個類,而是把類加載請求委派給BootStrapClassLoader去完成。

3.如果BootStrapClassLoader加載失敗(例如在$JAVA_HOME$/jre/lib里未查找到該class),會使用ExtClassLoader來嘗試加載;

4.若ExtClassLoader也加載失敗,則會使用AppClassLoader來加載,如果AppClassLoader也加載失敗,則會報出異常ClassNotFoundException。

下面貼下ClassLoader的loadClass(String name,boolean resolve)的源碼:

protected synchronized Class<?> loadClass(String name,boolean resolve)throws ClassNotFoundException{
        // 首先找緩存是否有 class
        Class c=findLoadedClass(name);
        if(c==null){
        //沒有判斷有沒有父類
        try{
        if(parent!=null){
        //有的話,用父類遞歸獲取 class
        c=parent.loadClass(name,false);
	}else{
        //沒有父類。通過這個方法來加載
        c=findBootstrapClassOrNull(name);}
        }catch(ClassNotFoundException e){
        // ClassNotFoundException thrown if class not found
        // from the non-null parent class loader
        }
        if(c==null){
        // 如果還是沒有找到,調用 findClass(name)去找這個類
        c=findClass(name);}
        }
        if(resolve){
        resolveClass(c);}
        return c;
        }

代碼很明朗:

首先找緩存(findLoadedClass),沒有的話就判斷有沒有parent,有的話就用parent來遞歸的loadClass,然而ExtClassLoader并沒有設置parent,則會通過findBootstrapClassOrNull來加載class,而findBootstrapClassOrNull則會通過JNI方法”private native Class findBootstrapClass(String name)”來使用BootStrapClassLoader來加載class。

如果parent未找到class,則會調用findClass來加載class,findClass是一個protected的空方法,可以覆蓋它以便自定義class加載過程。另外,雖然ClassLoader加載類是使用loadClass方法,但是鼓勵用ClassLoader的子類重寫findClass(String),而不是重寫loadClass,這樣就不會覆蓋了類加載默認的雙親委派機制。

雙親委派托機制為什么安全:

舉個例子,ClassLoader加載的class文件來源很多,比如編譯器編譯生成的class、或者網絡下載的字節碼。而一些來源的class文件是不可靠的,比如我可以自定義一個java.lang.Integer類來覆蓋jdk中默認的Integer類,例如下面這樣:

package java.lang;
public class Integer {
    public Integer(int value) {
        System.exit(0);
    }
}

初始化這個Integer的構造器是會退出JVM,破壞應用程序的正常進行,如果使用雙親委派機制的話該Integer類永遠不會被調用,以為委托BootStrapClassLoader加載后會加載JDK中的Integer類而不會加載自定義的這個,可以看下下面這測試個用例:

public static void main(String...args){
        Integer i=new Integer(1);
        System.err.println(i);
}

執行時JVM并未在new Integer(1)時退出,說明未使用自定義的Integer,于是就保證了安全性。

4、描述一下 JVM 加載 class?

JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實現的,Java中的類加載器是一個重要的Java運行時系統組件,它負責在運行時查找和裝入類文件中的類。

1.由于Java的跨平臺性,經過編譯的Java源程序并不是一個可執行程序,而是一個或多個類文件。

2.當Java程序需要使用某個類時,JVM會確保這個類已經被加載、連接(驗證、準備和解析)和初始化。類的加載是指把類的.class文件中的數據讀入到內存中,通常是創建一個字節數組讀入.class文件,然后產生與所加載類對應的Class對象。加載完成后,Class對象還不完整,所以此時的類還不可用。

3.當類被加載后就進入連接階段,這一階段包括驗證、準備(為靜態變量分配內存并設置默認的初始值)和解析(將符號引用替換為直接引用)三個步驟。最后JVM對類進行初始化,包括:如果類存在直接的父類并且這個類還沒有被初始化,那么就先初始化父類;如果類中存在初始化語句,就依次執行這些初始化語句。

4.類的加載是由類加載器完成的,類加載器包括:根加載器(BootStrap)、擴展加載器(Extension)、系統加載器(System)和用戶自定義類加載器(java.lang.ClassLoader的子類)。

5.從Java 2(JDK 1.2)開始,類加載過程采取了父親委托機制(PDM)。PDM更好的保證了Java平臺的安全性,在該機制中,JVM自帶的Bootstrap是根加載器,其他的加載器都有且僅有一個父類加載器。類的加載首先請求父類加載器加載,父類加載器無能為力時才由其子類加載器自行加載。JVM不會向Java程序提供對Bootstrap的引用。

● 下面是關于幾個類加載器的說明:

1.Bootstrap:一般用本地代碼實現,負責加載JVM基礎核心類庫(rt.jar);

2.Extension:從java.ext.dirs系統屬性所指定的目錄中加載類庫,它的父加載器是Bootstrap;

3.System:又叫應用類加載器,其父類是Extension。它是應用最廣泛的類加載器。它從環境變量classpath或者系統屬性java.class.path所指定的目錄中記載類,是用戶自定義加載器的默認父加載器。

5、獲得一個類對象有哪些方式?

● 類型.class,例如:String.class;

● 對象.getClass(),例如:”hello”.getClass();

● Class.forName(),例如:Class.forName(“java.lang.String”);

全部教程
主站蜘蛛池模板: 日韩天天摸天天澡天天爽视频 | 新久草视频 | 欧美.成人.综合在线 | 中文字幕或区 | 香蕉免费一区二区三区在线观看 | 国产亚洲精品麻豆一区二区 | 久久精品国产亚洲沈樵 | 国产精品视频一区二区三区 | 国产美女久久精品香蕉69 | 国产国产成人人免费影院 | 欧美一级日韩 | 牛牛色婷婷在线视频播放 | 亚洲久操| 精品99re66| 香蕉视频网站免费观视频 | 国产精品亚洲午夜不卡 | 欧美一级欧美三级 | 四虎影院一级片 | 久久99影院网久久久久久 | 亚洲 日本 欧美 中文幕 | 亚洲大片免费看 | 亚洲欧美综合一区二区三区四区 | 久久青草免费91观看 | 在线播放波多野结衣 | 色婷婷欧美 | 久久成人免费观看全部免费 | 性欧美xo视频在线观看 | 大ji吧快给我别停受不了视频 | 日本中文字幕高清 | 久久精品国产精品国产精品污 | 成人短视频在线在线观看 | 亚洲一区精品视频在线 | 亚洲国产观看 | 国产精片 | 综合图区亚洲白拍在线 | 性a爱片免费视频性 | 欧美成人精品欧美一级乱黄 | 国产在线原创剧情麻豆 | 亚洲精品久久久久久久福利 | 日本高清不卡在线 | 欧美成人午夜视频在线观看 |