乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      全面解析Java類(lèi)加載器

       liang1234_ 2019-04-16

      深入理解和探究Java類(lèi)加載機(jī)制----

      1.java.lang.ClassLoader類(lèi)介紹

      java.lang.ClassLoader類(lèi)的基本職責(zé)就是根據(jù)一個(gè)指定的類(lèi)的名稱,找到或者生成其對(duì)應(yīng)的字節(jié)代碼,然后從這些字節(jié)代碼中定義出一個(gè)Java 類(lèi),即 java.lang.Class類(lèi)的一個(gè)實(shí)例。

      ClassLoader提供了一系列的方法,比較重要的方法如:

       

       

      2.JVM中類(lèi)加載器的樹(shù)狀層次結(jié)構(gòu)

      Java 中的類(lèi)加載器大致可以分成兩類(lèi),一類(lèi)是系統(tǒng)提供的,另外一類(lèi)則是由 Java 應(yīng)用開(kāi)發(fā)人員編寫(xiě)的。 

      引導(dǎo)類(lèi)加載器(bootstrap class loader):

      它用來(lái)加載 Java 的核心庫(kù)(jre/lib/rt.jar),是用原生C++代碼來(lái)實(shí)現(xiàn)的,并不繼承自java.lang.ClassLoader。

      加載擴(kuò)展類(lèi)和應(yīng)用程序類(lèi)加載器,并指定他們的父類(lèi)加載器,在java中獲取不到。 

      擴(kuò)展類(lèi)加載器(extensions class loader):

      它用來(lái)加載 Java 的擴(kuò)展庫(kù)(jre/ext/*.jar)。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類(lèi)加載器在此目錄里面查找并加載 Java 類(lèi)。 

      系統(tǒng)類(lèi)加載器(system class loader):

      它根據(jù) Java 應(yīng)用的類(lèi)路徑(CLASSPATH)來(lái)加載 Java 類(lèi)。一般來(lái)說(shuō),Java 應(yīng)用的類(lèi)都是由它來(lái)完成加載的??梢酝ㄟ^(guò) ClassLoader.getSystemClassLoader()來(lái)獲取它。

      自定義類(lèi)加載器(custom class loader):

      除了系統(tǒng)提供的類(lèi)加載器以外,開(kāi)發(fā)人員可以通過(guò)繼承 java.lang.ClassLoader類(lèi)的方式實(shí)現(xiàn)自己的類(lèi)加載器,以滿足一些特殊的需求。

       

      以下測(cè)試代碼可以證明此層次結(jié)構(gòu):

      復(fù)制代碼
      public class testClassLoader {
          @Test
          public void test(){
              //application class loader
              System.out.println(ClassLoader.getSystemClassLoader());
              //extensions class loader
              System.out.println(ClassLoader.getSystemClassLoader().getParent());
              //bootstrap class loader
              System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());
          }
      }
      復(fù)制代碼

      輸出為:

       

      可以看出ClassLoader類(lèi)是由AppClassLoader加載的。他的父親是ExtClassLoader,ExtClassLoader的父親無(wú)法獲取是因?yàn)樗怯肅++實(shí)現(xiàn)的。

       

      3.雙親委派機(jī)制

        某個(gè)特定的類(lèi)加載器在接到加載類(lèi)的請(qǐng)求時(shí),首先將加載任務(wù)委托交給父類(lèi)加載器,父類(lèi)加載器又將加載任務(wù)向上委托,直到最父類(lèi)加載器,如果最父類(lèi)加載器可以完成類(lèi)加載任務(wù),就成功返回,如果不行就向下傳遞委托任務(wù),由其子類(lèi)加載器進(jìn)行加載。

      雙親委派機(jī)制的好處:

        保證java核心庫(kù)的安全性(例如:如果用戶自己寫(xiě)了一個(gè)java.lang.String類(lèi)就會(huì)因?yàn)殡p親委派機(jī)制不能被加載,不會(huì)破壞原生的String類(lèi)的加載)

      代理模式

        與雙親委派機(jī)制相反,代理模式是先自己嘗試加載,如果無(wú)法加載則向上傳遞。tomcat就是代理模式。

       

      4.自定義類(lèi)加載器

      復(fù)制代碼
      public class MyClassLoader extends ClassLoader{
      
          private String rootPath;
          
          public MyClassLoader(String rootPath){
              this.rootPath = rootPath;
          }
          
          @Override
          protected Class<?> findClass(String name) throws ClassNotFoundException {
              //check if the class have been loaded
              Class<?> c = findLoadedClass(name);        
              if(c!=null){
                  return c;
              }
              //load the class
              byte[] classData = getClassData(name);
              if(classData==null){
                  throw new ClassNotFoundException();
              }
              else{
                  c = defineClass(name,classData, 0, classData.length);
                  return c;
              }    
          }
          
          private byte[] getClassData(String className){
              String path = rootPath+"/"+className.replace('.', '/')+".class";
              
              InputStream is = null;
              ByteArrayOutputStream bos = null;
              try {
                  is = new FileInputStream(path);
                  bos = new ByteArrayOutputStream();
                  byte[] buffer = new byte[1024];
                  int temp = 0;
                  while((temp = is.read(buffer))!=-1){
                      bos.write(buffer,0,temp);
                  }
                  return bos.toByteArray();
              } catch (Exception e) {
                  e.printStackTrace();
              }finally{
                  try {
                      is.close();
                      bos.close();
                  } catch (Exception e) {
                      e.printStackTrace();
                  }            
              }
              
              return null;        
          }    
      
      }
      復(fù)制代碼

      測(cè)試自定義的類(lèi)加載器

      創(chuàng)建一個(gè)測(cè)試類(lèi)HelloWorld

      package testOthers;
      
      public class HelloWorld {
      
      }

      在D盤(pán)根目錄創(chuàng)建一個(gè)testOthers文件夾,編譯HelloWorld.java,將得到的class文件放到testOthers文件夾下。

      利用如下代碼進(jìn)行測(cè)試

      復(fù)制代碼
      public class testMyClassLoader {
          @Test
          public void test() throws Exception{
              MyClassLoader loader = new MyClassLoader("D:");
              Class<?> c = loader.loadClass("testOthers.HelloWorld");
              System.out.println(c.getClassLoader());
          }
      }
      復(fù)制代碼

      輸出:

       

      說(shuō)明HelloWorld類(lèi)是被我們的自定義類(lèi)加載器MyClassLoader加載的

       

      5.類(lèi)加載過(guò)程詳解

      JVM將類(lèi)加載過(guò)程分為三個(gè)步驟:裝載(Load),鏈接(Link)和初始化(Initialize)

      1) 裝載

        查找并加載類(lèi)的二進(jìn)制數(shù)據(jù);

      2)鏈接

        驗(yàn)證:確保被加載類(lèi)信息符合JVM規(guī)范、沒(méi)有安全方面的問(wèn)題。

        準(zhǔn)備:為類(lèi)的靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值。

        解析:把虛擬機(jī)常量池中的符號(hào)引用轉(zhuǎn)換為直接引用。

      3)初始化

        為類(lèi)的靜態(tài)變量賦予正確的初始值。

      ps:解析部分需要說(shuō)明一下,Java 中,虛擬機(jī)會(huì)為每個(gè)加載的類(lèi)維護(hù)一個(gè)常量池【不同于字符串常量池,這個(gè)常量池只是該類(lèi)的字面值(例如類(lèi)名、方法名)和符號(hào)引用的有序集合。 而字符串常量池,是整個(gè)JVM共享的】這些符號(hào)(如int a = 5;中的a)就是符號(hào)引用,而解析過(guò)程就是把它轉(zhuǎn)換成指向堆中的對(duì)象地址的相對(duì)地址。

       

      類(lèi)的初始化步驟:

      1)如果這個(gè)類(lèi)還沒(méi)有被加載和鏈接,那先進(jìn)行加載和鏈接

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

      3)如果類(lèi)中存在static標(biāo)識(shí)的塊,那就依次執(zhí)行這些初始化語(yǔ)句。

       

       

       

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類(lèi)似文章 更多