<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    MDA/MDD/TDD/DDD/DDDDDDD
    posts - 536, comments - 111, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    java類的加載

    Posted on 2011-02-24 17:58 leekiang 閱讀(420) 評論(0)  編輯  收藏 所屬分類: java
    打印Thread.currentThread().getContextClassLoader(),顯示如下:
    sun.misc.Launcher$AppClassLoader@19821f
    這個加載器是系統類加載器。ClassLoader.getSystemResourceAsStream("com/config.xml")使用的就是系統類加載器定位資源的。


    ??? //JDK1.6,java.lang.ClassLoader的loadClass(String?name,?boolean?resolve)方法的源碼
    protected?synchronized?Class<?>?loadClass(String?name,?boolean?resolve)
    ????
    throws?ClassNotFoundException
    ????{
    ????
    //?First,?check?if?the?class?has?already?been?loaded
    ????Class?c?=?findLoadedClass(name);
    ????
    if?(c?==?null)?{
    ????????
    try?{
    ????????
    if?(parent?!=?null)?{
    ?????????? //
    如果parent不為null,則調用parent的loadClass進行加載?
    ????????????c?=?parent.loadClass(name,?false);
    ????????}?
    else?{
    ?????????? //
    parent為null,則調用BootstrapClassLoader進行加載
    ????????????c?=?findBootstrapClassOrNull(name);
    ????????}
    ????????}?
    catch?(ClassNotFoundException?e)?{
    ????????????????
    //?ClassNotFoundException?thrown?if?class?not?found
    ????????????????
    //?from?the?non-null?parent?class?loader
    ???????? }
    ???????
    if?(c?==?null)?{
    ????????????
    //?If?still?not?found,?then?invoke?findClass?in?order to?find?the?class.
    ??????????? //
    如果仍然無法加載成功,則調用自身的findClass進行加載
    ????????????c?=?findClass(name);
    ????????}
    ????}
    ????
    if?(resolve)?{
    ????????resolveClass(c);
    ????}
    ????
    return?c;
    ????}

    java中共有三種類型的類加載器:
    ??? 1、引導(bootstrap)類加載器(用來加載java API類),例如加載java.lang.String類
    ??? 2、擴展類加載器(就是sun.misc.Launcher$ExtClassLoader,用來加載jre\lib\ext目錄下的jar包)
    ??? 3、系統類加載器(就是sun.misc.Launcher$AppClassLoader,主要用來加載CLASSPATH設置目錄中的Class)

    創建一個URLClassLoader,發現其父加載器(parent,注意不是父類)的類型為sun.misc.Launcher$AppClassLoader,而sun.misc.Launcher$AppClassLoader和sun.misc.Launcher$ExtClassLoader的父類都是URLClassLoader。AppClassLoader的父加載器是ExtClassLoader,ExtClassLoader的父加載器為null,即bootstrap類加載器。

    類加載有個雙親委托模式,
    AppClassLoader的父加載器是ExtClassLoader ,ExtClassLoader 的父加載器是bootstrap classloader,bootstrap 是C++寫的類加載器,會負責加載java核心類庫,就是jre/lib/rt.jar
    ExtClassLoader會加載擴展類庫,就是jre/lib/ext下的庫。

    雙親委托模式就是子加載器會先委托父加載器加載,父加載器加載不了子加載器才加載,
    這樣做避免了重復加載,也加強了java的安全了,防止了惡意加載器去加載核心庫。

    String?name?=?"com.domain.Account";
    ????????????
    ????????????URL?url1?
    =?new?URL("file:/D:/workspace/test/bin/");
    ????????????ClassLoader?cl?
    =?new?URLClassLoader(new?URL[]?{?url1?});
    ????????????Class?c1?
    =?cl.loadClass(name);
    ????????????
    ????????????URL?url2?
    =?new?URL("file:/D:/workspace/test/bin");
    ????????????ClassLoader?cl2?
    =?new?URLClassLoader(new?URL[]?{?url2?});
    ????????????Class?c2?
    =?cl2.loadClass(name);
    ????????????
    ????????????System.out.println(c1
    ==c2);//返回true,原因是都是用系統類加載器AppClassLoader加載的

    注意:
    1,在類A中使用Class.forName加載類B,那么加載類A的類加載器將會用于加載類B,這樣兩個類的類加載器是同一個。
    2,Class.forName("")和classLoader.load("")的區別主要是前者會做初始化,后者不會。見jdk注釋:A?call?to?forName("X")?causes?the?class?named?X?to?be?initialized.? 自己分別用兩種方式裝載一個帶靜態代碼的類就知道了。jdbc需要通過Class.forName("")的方式來裝載JDBC驅動程序(例如 Class.forName("com.mysql.jdbc.Driver"),之所以用Class.forName而沒有用 ClassLoader.load(),就是因為需要JVM完成Driver的初始化工作,而不僅僅是裝載),然后通過一個統一的工廠類 Java.sql.DriverManager來取得數據庫連接,并執行各種操作。Class.forName("")不僅load?class而且還保證resolve這個class,包括常量池解析,類初始化。。。這樣JDBC驅動使用這個方法,才能保證類里的靜態方法執行,一般驅動類的靜態方法會向DriverManager注冊自己,如果用classloader.load("")就不一定會resolve這個class,也就不能保證注冊驅動類!
    看了com.mysql.jdbc.Driver類的源碼,靜態代碼就一句:java.sql.DriverManager.registerDriver(new com.mysql.jdbc.Driver())
    3,

    參考
    1)java系統類加載器AppClassLoader之淺談 http://blog.sina.com.cn/s/blog_4db6a3f101000do1.html
    2)java類加載原理分析 http://gongmingwind.javaeye.com/blog/338366
    3)解讀ClassLoader http://www.javaeye.com/topic/83978
    4)http://xyiyy.javaeye.com/blog/362107

    Retrotranslator是一個Java字節碼轉換工具。它能夠把用JDK5.0編譯的Java Class轉換成可運行在JVM1.4
    主站蜘蛛池模板: 亚洲视频在线一区二区| 在线观看亚洲免费| 亚洲精品国产成人片| 无码毛片一区二区三区视频免费播放| 国产成人在线观看免费网站| 蜜桃传媒一区二区亚洲AV| 免费高清在线影片一区| 国产产在线精品亚洲AAVV| 一本色道久久88亚洲综合| 午夜不卡AV免费| 亚洲国产另类久久久精品| 国产精品白浆在线观看免费| 久久久久亚洲精品日久生情| 波多野结衣免费在线观看| 亚洲中文字幕无码一去台湾| 在线看片无码永久免费aⅴ| 免费福利资源站在线视频| 久久久久亚洲精品中文字幕| 国产一区二区三区免费观看在线| 亚洲最新永久在线观看| 日韩欧美一区二区三区免费观看 | 国产午夜无码精品免费看动漫| 亚洲AV成人无码久久精品老人 | 亚洲视频网站在线观看| 99视频在线精品免费观看6| 国产成人精品日本亚洲语音 | 亚洲大尺度无码无码专线一区| 免费国产在线观看| 久久九九免费高清视频| 亚洲毛片无码专区亚洲乱| 成年男女免费视频网站| 国产成人精品免费大全| 亚洲激情视频网站| 免费看a级黄色片| 花蝴蝶免费视频在线观看高清版| 亚洲va精品中文字幕| 久久亚洲国产精品123区| 久久久久av无码免费网| 黄色免费网址大全| 亚洲日本在线免费观看| 亚洲精品人成无码中文毛片|