1. 程式人生 > 實用技巧 >【執行機制】 JavaScript的事件迴圈機制總結 eventLoop

【執行機制】 JavaScript的事件迴圈機制總結 eventLoop

一、類載入過程

一個非陣列類的載入階段(載入階段通過一個類的全限定名來獲取描述此類的二進位制位元組流的動作)是可控性最強的階段,這一步我們可以去完成還可以自定義類載入器去控制位元組流的獲取方式(重寫一個類載入器的loadClass()方法),這個動作放到Java虛擬機器外部去實現陣列型別不通過類載入器建立,它由 Java 虛擬機器直接建立

類載入器用於實現類的載入動作。

二、

package JvmTest;

import java.io.IOException;
import java.io.InputStream;

/*
 * 類載入器與instanceof關鍵字演示
 *   (1)Java序列化就是指把Java物件轉換為位元組序列的過程
 *   (2)Java反序列化就是指把位元組序列恢復為Java物件的過程。
 
*/ public class Nine { public static void main(String[] args) throws Exception{ //自己重寫的類載入器 ClassLoader myLoader = new ClassLoader() { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { try{
//載入在同一路徑下Class檔案 String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; InputStream is = getClass().getResourceAsStream(fileName); if(is == null){ return super.loadClass(name); }
//位元組流讀取 byte[] b = new byte[is.available()]; is.read(b); return defineClass(name, b, 0, b.length); // 把自己位元組序列恢復成Java物件 }catch (IOException e){ throw new ClassNotFoundException(name); } } }; //使用myloader類載入去載入名為JvmTest.Nine的類,並例項化物件obj Object obj = myLoader.loadClass("JvmTest.Nine").newInstance(); System.out.println(obj.getClass()); //物件obj的確是類JvmTest.Nine例項化的物件
     //instanceof Java中的一個雙目運算子,用來測試一個物件是否為一個類的例項
System.out.println(obj instanceof JvmTest.Nine); //所屬類檢查,判斷obj是否屬於類 } }
class JvmTest.Nine
false

上述程式碼重寫了一個類載入器,使用這個類載入器去載入一個名為JvmTest.Nine的類,並建立了一個物件obj。結果發現obj的確是JvmTest.Nine的一個例項,但是做物件所屬類檢查的時候,卻輸出false。原因如下:

因為虛擬機器出現了兩個JvmTest.Nine類,一個是系統應用程式類載入器載入的,另一個是自定義myLoader類載入器載入的。雖然都來自同一個Class檔案,但確實不同的獨立的類。再次驗證那句話:

即使兩個類來源於同一個Class檔案,被同一個虛擬機器載入,只要載入他們的類載入器不同,那麼這兩個類就不相等。

三、雙親委派模型

從Java虛擬機器的角度來講,只存在兩種不同的類載入器:

  1. 啟動類載入器(Bootstrap ClassLoader),這個類載入器使用C++語言實現,是虛擬機器自身的一部分
  2. 除了啟動類載入器的所有其他類載入器,這些類載入器由Java語言實現,獨立於虛擬機器外部,並且全部繼承自抽象類java.lang.ClassLoader。

類載入器可以劃分得更細緻一些,主要分為以下三種:

  1. 啟動類載入器(Bootstrap ClassLoader),最頂層的類載入器,由C++實現,無法被Java程式直接引用。負責載入<JAVA_HOME>\lib目錄下的jar包的類或者被-Xbootclasspath引數所指定的路徑中的所有類。
  2. 擴充套件類載入器(Extension ClassLoader),主要負責載入<JAVA_HOME>\lib\ext目錄下的jar包和類,或被java.ext.dirs系統變數所指定的路徑中所有類庫,開發者是可以直接使用的。
  3. 應用程式類載入器(Application ClassLoader),面向我們使用者的載入器,負責載入當前應用classpath(使用者類路徑)下的所有jar包和類。應用程式類載入器也稱為系統類載入器。

類載入器的雙親委派模型

每一個類都有一個對應它的類載入器。系統中的ClassLoader在協同工作的時候會預設使用雙親委派模型:在類載入的時候,系統會首先判斷當前類是否被載入過,已經被載入的類會直接返回,否則才會嘗試載入。首先會把該請求委派父類載入器的loadClass()處理,因此所有的請求最終都應該傳送到頂層的啟動類載入器BootstrapClassLoader中。當父類載入器無法處理時,才由自己來處理。當父類載入器為null時,會使用啟動類載入器BootstrapClassLoader作為父類載入器。流程圖如下所示: