| 一個jvm進程中的內(nèi)存和其他進程之間不產(chǎn)生影響。 一.類的加載: 當一個類加載到j(luò)vm內(nèi)存中需要通常是連續(xù)的3個步驟:將class文件加載到內(nèi)存中, 并建立class 對象(java.lang.class ) 是類加載的本意和最終狀態(tài)。 1.加載:由類加載器進行加載,jvm提供類加載器,也可以通過繼承classRoader實現(xiàn)自定義的類加載器。 2.連接:生成對應(yīng)的class對象后就進入連接狀態(tài) 把類的二進制數(shù)據(jù)加載到JRE中了。 (1).驗證 加載類是否有正確的結(jié)構(gòu) (2).準備:給類的靜態(tài)Field分配內(nèi)存,初值 (3).解析:將類的二進制數(shù)據(jù)中符號應(yīng)用換成直接引用 3.初始化:正常的類初始化,執(zhí)行順序。 二.類加載器: jvm 啟動時會形成3層類加載器結(jié)構(gòu): 1:Bootstarp ClassLoader 根加載,當執(zhí)行java.exe命令時會 加載java內(nèi)核不是Java.lang.ClassLoader的子類。不是由java語言實現(xiàn)的。2: Extension ClassLoader 擴展類加載器,負責加載JRE的擴展目錄下的Class JAR包下的類。 3: System ClassLoader 系統(tǒng)(應(yīng)用)類加載器, jvm啟動時加載classpath 路徑下的包和類路徑。 自定義的加載器以類加載器作為父加載器。 后兩者 e是s的父類加載器,但沒有繼承關(guān)系。系統(tǒng)類加載器的實例是APPClassLoader,擴展類加載器的實例是ExtClassLoader。 這兩個類都是URLClassLoader類的實例。 三.類加載的機制: 2.父類委托:先讓父類加載,如果父類無法加載,才嘗試從自己的類路徑中加載。當父類為null時,JVM內(nèi)置的類(稱為:bootstrap class loader)就會充當父類。 3.緩存機制:先在緩存區(qū)中找,不存在才讀取轉(zhuǎn)換。 四.自定義類加載器: 根據(jù)父類委托,若父類無法找到則調(diào)用當前加載器找,繼承并重寫classLoader中方法實現(xiàn)自定義類加載器,loadClass()和findclass()方法。 事實上,只重寫findClass可以避免父類委托和緩沖兩種機制的覆蓋。 同時該類還有一些無法覆寫的方法,eg:defineClass 該方法用于將將類的字節(jié)碼文字寫入到byte[]數(shù)組中,并轉(zhuǎn)化為class對象。 自定義加載器可以實現(xiàn)某些功能:eg:執(zhí)行前檢測簽名。其實通過XML文檔描述的配置信息最終都要變成Java類,其實都是通過ClassLoader來完成的。 eg: **      * 一、ClassLoader加載類的順序      *  1.調(diào)用 findLoadedClass(String) 來檢查是否已經(jīng)加載類。      *  2.在父類加載器上調(diào)用 loadClass 方法。如果父類加載器為 null,則使用虛擬機的內(nèi)置類加載器。      *  3.調(diào)用 findClass(String) 方法查找類。      * 二、實現(xiàn)自己的類加載器      *  1.獲取類的class文件的字節(jié)數(shù)組      *  2.將字節(jié)數(shù)組轉(zhuǎn)換為Class類的實例      * @author lei 2011-9-1      */      public class ClassLoaderTest {          public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {              //新建一個類加載器              MyClassLoader cl = new MyClassLoader('myClassLoader');              //加載類,得到Class對象              Class> clazz = cl.loadClass('classloader.Animal');              //得到類的實例              Animal animal=(Animal) clazz.newInstance();              animal.say();          }      }      class Animal{          public void say(){              System.out.println('hello world!');          }      }      class MyClassLoader extends ClassLoader {          //類加載器的名稱          private String name;          //類存放的路徑          private String path = 'E:\\workspace\\Algorithm\\src';          MyClassLoader(String name) {              this.name = name;          }          MyClassLoader(ClassLoader parent, String name) {              super(parent);              this.name = name;          }          /**          * 重寫findClass方法          */          @Override          public Class> findClass(String name) {              byte[] data = loadClassData(name);              return this.defineClass(name, data, 0, data.length);          }          public byte[] loadClassData(String name) {              try {                  name = name.replace('.', '//');                  FileInputStream is = new FileInputStream(new File(path + name + '.class'));                  ByteArrayOutputStream baos = new ByteArrayOutputStream();                  int b = 0;                  while ((b = is.read()) != -1) {                      baos.write(b);                  }                  return baos.toByteArray();              } catch (Exception e) {                  e.printStackTrace();              }              return null;          }      }   五.URLClassLoader 作用:既可以本地獲取二進制文件,也可以從遠程主機獲取二進制文件,構(gòu)造方法兩種: 1:默認的父類加載器創(chuàng)建一個classLoader ,并從urls指定的路徑獲取 2:使用指定父類的加載器創(chuàng)建一個ClassLoader,得到URLClassLoader后就可調(diào)用loadClass 方法來加載指定的類了。 用法:  URL   url   =   file.toURI().toURL();   URLClassLoader   loader   =   new   URLClassLoader(new   URL[]   {   url   });     Class   tidyClazz   =   loader.loadClass(所需class的含包名的全名);  | 
|  |