国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java類加載器詳解

Baaaan / 1266人閱讀

摘要:當一個文件是通過網(wǎng)絡(luò)傳輸并且可能會進行相應(yīng)的加密操作時,需要先對文件進行相應(yīng)的解密后再加載到內(nèi)存中,這種情況下也需要編寫自定義的并實現(xiàn)相應(yīng)的邏輯

Java虛擬機中的類加載有三大步驟:,鏈接,初始化.其中加載是指查找字節(jié)流(也就是由Java編譯器生成的class文件)并據(jù)此創(chuàng)建類的過程,這中間我們需要借助類加載器來查找字節(jié)流.

Java虛擬機默認類加載器

Java虛擬機提供了3種類加載器,啟動(Bootstrap)類加載器、擴展(Extension)類加載器、應(yīng)用(Application)類加載器.除了啟動類加載器外,其他的類加載器都是java.lang.ClassLoader的子類.啟動類加載器由C++語言實現(xiàn),沒有對應(yīng)的Java對象,它負責將 /lib路徑下的核心類庫或-Xbootclasspath參數(shù)指定的路徑下的jar包加載到內(nèi)存中.擴展類加載器是指sun.misc.Launcher$ExtClassLoader類,由Java語言實現(xiàn),是Launcher的靜態(tài)內(nèi)部類,它負責加載/lib/ext目錄下或者由系統(tǒng)變量-Djava.ext.dir指定位路徑中的類庫,他的父類加載器是null.應(yīng)用類加載器是指sun.misc.Launcher$AppClassLoader類,他負責加載應(yīng)用程序路徑下的類,這里路徑指java -classpath或-D java.class.path 指定的路徑,他的父類加載器是擴展類加載器.

注意這里面的父子類加載器并不是繼承的關(guān)系,只是ClassLoader類中的parent屬性.我們來看Launcher類中創(chuàng)建擴展類加載器的代碼:

public ExtClassLoader(File[] var1) throws IOException {
      super(getExtURLs(var1), (ClassLoader)null, Launcher.factory);
      SharedSecrets.getJavaNetAccess().getURLClassPath(this).initLookupCache(this);
    }

這里設(shè)置了其父加載器為null.

雙親委派機制

Java虛擬機在加載類時默認采用的是雙親委派機制,即當一個類加載器接收到加載請求時,會將請求轉(zhuǎn)發(fā)到父類加載器,如果父類加載器在路徑下沒有找到該類,才會交給子類加載器去加載.我們來看ClassLoader中l(wèi)aodClass方法:

protected Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 首先判斷類是否已加載過,加載過就直接返回
            Class c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        //有父類加載器,調(diào)用父加載器的loadClass
                        c = parent.loadClass(name, false);
                    } else {
                        //調(diào)用Bootstrap Classloader
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    long t1 = System.nanoTime();
                    //到自己指定類加載路徑下查找是否有class字節(jié)碼
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

通過這種層級我們可以避免類的重復(fù)加載,當父親已經(jīng)加載了該類時,就沒有必要子類加載器再加載一次。其次也考慮到安全因素,比如我們自己寫一個java.lang.String的類,通過雙親委派機制傳遞到啟動類加載器,而啟動類加載器在核心Java API發(fā)現(xiàn)這個名字的類,發(fā)現(xiàn)該類已被加載,并不會重新加載我們新寫的java.lang.String,而直接返回已加載過的String.class,這樣保證生成的對象是同一種類型.

自定義類加載器

除了jvm自身提供的類加載器,我們還可以自定義類加載器,我們先寫一個Person類

public class Person {

  private int age;

  private String name;

  //省略getter/setter方法
}

我們先看他是由哪個類加載器加載的.

public class TestJava {

  public static void main(String[] args) throws Exception {
    Person person = new Person();
    System.out.println("person是由" + person.getClass().getClassLoader() + "加載的");
  }
}

運行結(jié)果如下:

我們把Person.class放置在其他目錄下

再運行會發(fā)生什么,在上面的loadClass方法中其實已經(jīng)有了答案,會拋出ClassNotFoundException,因為在指定路徑下查找不到字節(jié)碼.

我們現(xiàn)在寫一個自定義的類加載器,讓他能夠去加載person類,很簡單,我們只需要繼承ClassLoader并重寫findClass方法,這里面寫查找字節(jié)碼的邏輯.

public class PersonCustomClassLoader extends ClassLoader {

  private String classPath;

  public PersonCustomClassLoader(String classPath) {
    this.classPath = classPath;
  }

  private byte[] loadByte(String name) throws Exception {
    name = name.replaceAll(".", "/");
    FileInputStream fis = new FileInputStream(classPath + "/" + name
        + ".class");
    int len = fis.available();
    byte[] data = new byte[len];
    fis.read(data);
    fis.close();
    return data;

  }

  protected Class findClass(String name) throws ClassNotFoundException {
    try {
      byte[] data = loadByte(name);
      return defineClass(name, data, 0, data.length);
    } catch (Exception e) {
      e.printStackTrace();
      throw new ClassNotFoundException();
    }
  }
}

我們來測試一下:

public class TestJava {

  public static void main(String[] args) throws Exception {
    PersonCustomClassLoader classLoader = new PersonCustomClassLoader("/home/shenxinjian");
    Class pClass = classLoader.loadClass("me.shenxinjian.algorithm.Person");
    System.out.println("person是由" + pClass.getClassLoader() + "類加載器加載的");

  }
}

測試結(jié)果如下:

編寫自定義類加載器的意義

當class文件不在classPath路徑下,如上面那種情況,默認系統(tǒng)類加載器無法找到該class文件,在這種情況下我們需要實現(xiàn)一個自定義的classLoader來加載特定路徑下的class文件來生成class對象。

當一個class文件是通過網(wǎng)絡(luò)傳輸并且可能會進行相應(yīng)的加密操作時,需要先對class文件進行相應(yīng)的解密后再加載到JVM內(nèi)存中,這種情況下也需要編寫自定義的ClassLoader并實現(xiàn)相應(yīng)的邏輯

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/73405.html

相關(guān)文章

  • 關(guān)于ClassLoader的學(xué)習筆記,詳解

    摘要:它負責將的字節(jié)碼形式轉(zhuǎn)換成內(nèi)存形式的對象。先使用工具對字節(jié)碼文件進行加密,運行時使用定制的先解密文件內(nèi)容再加載這些解密后的字節(jié)碼。的方法是需要子類來覆蓋的,不同的加載器將使用不同的邏輯來獲取目標類的字節(jié)碼。 ClassLoader 詳解 ClassLoader 做什么的? 延遲加載 各司其職 ClassLoader 傳遞性 雙親委派 Class.forName 自定義加載器 Clas...

    zgbgx 評論0 收藏0
  • JVM_加載機制詳解

    摘要:加載器種類啟動類加載器在中用來加載自身需要的類,實現(xiàn),用來加載。那么就能保證的類會被優(yōu)先加載,限制了使用者對系統(tǒng)的影響。這種方式下就完成類加載器的雙親委派機制此處會將作為參數(shù)傳入進去實際上是調(diào)用了方法 Class 文件的裝載流程 (類加載過程) 加載 -> 連接 (驗證 -> 準備 -> 解析) -> 初始化 -> 使用 -> 卸載 加載 加載階段,jvm 會通過類名獲取到此類的字節(jié)碼...

    MasonEast 評論0 收藏0
  • Java面試 32個核心必考點完全解析

    摘要:如問到是否使用某框架,實際是是問該框架的使用場景,有什么特點,和同類可框架對比一系列的問題。這兩個方向的區(qū)分點在于工作方向的側(cè)重點不同。 [TOC] 這是一份來自嗶哩嗶哩的Java面試Java面試 32個核心必考點完全解析(完) 課程預(yù)習 1.1 課程內(nèi)容分為三個模塊 基礎(chǔ)模塊: 技術(shù)崗位與面試 計算機基礎(chǔ) JVM原理 多線程 設(shè)計模式 數(shù)據(jù)結(jié)構(gòu)與算法 應(yīng)用模塊: 常用工具集 ...

    JiaXinYi 評論0 收藏0
  • Java反射機制詳解

    摘要:反射機制的應(yīng)用實例在泛型為的中存放一個類型的對象。工廠模式可以參考現(xiàn)在我們利用反射機制實現(xiàn)工廠模式,可以在不修改工廠類的情況下添加任意多個子類。 學(xué)習交流群:669823128java 反射 定義 功能 示例概要:Java反射機制詳解| |目錄 1反射機制是什么 2反射機制能做什么 3反射機制的相關(guān)API 通過一個對象獲得完整的包名和類名 實例化Class類對象 獲取一個對象的父類與...

    paraller 評論0 收藏0
  • 四年來Android面試大綱,作為一個Android程序員

    摘要:再附一部分架構(gòu)面試視頻講解本文已被開源項目學(xué)習筆記總結(jié)移動架構(gòu)視頻大廠面試真題項目實戰(zhàn)源碼收錄 Java反射(一)Java反射(二)Java反射(三)Java注解Java IO(一)Java IO(二)RandomAccessFileJava NIOJava異常詳解Java抽象類和接口的區(qū)別Java深拷貝和淺拷...

    不知名網(wǎng)友 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<