Class Loading ---(類裝載機制,開發人員不得不知道的故事) --上篇

來源:互聯網
上載者:User
 也許你認為Class Load是一個進階話題,不管怎樣,作為開發人員你還是要瞭解它。 本文基於最新得JDK5,然後將將訴的內容都包含了最基本的原理,希望你能更加深入瞭解自己所使用得語言。   理解CLassLoader 如果你自己定義叻一個 org.test.Object 。你在程式中這樣寫:import ort.test.ObjectObject o = new String(); 
也許你欣然以為這樣寫沒問題,但實際上你錯了。  這樣是不正確的,會報 ClassCastException,一個Class在JVM中得標識呢是由它得 PackAge 和 類名決定得。 也就是它得名稱空間。 org.test.Object 可不是  java.lang.Object 在java中呢,每個類都是java.lang.Class得執行個體。也就是說。
java.lang.Class klass = Myclass.class;
Myclass myclass  = new Myclass() 等同於  myclass.newInstance();
  在JVM中。所有得類都由 java.lang.ClassLoader.(或者是它得子類開發人員自己添加得),我們在啟動得時候都是借力於JAVA_HOME/jre/rt.jar。  不過我們發現JDK這裡並沒有任何文檔介紹bootstrap.jar。 實際上bootstrap Class Loader是JDK之外得,它得方式和JVM的是不一樣的。(本文不做介紹)
  • java.net.URLClassLoader
  • java.security.SecureClassLoader
  • java.rmi.server.RMIClassLoader
  • sun.applet.AppletClassLoader
Class Loaders工作原理     除了bootstrap之外,所有的Classloader都有個父類Class Loader ,他們都是instanceof java.lang.ClassLoader  來看看JDK1.5中的工作原理。假如有個方法loadClass protected synchronized Class<?> loadClass
    (String name, boolean resolve)
    throws ClassNotFoundException{

    // First check if the class is already loaded
    Class c = findLoadedClass(name);
    if (c == null) {
        try {
            if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClass0(name);
            }
        } catch (ClassNotFoundException e) {
            // If still not found, then invoke
            // findClass to find the class.
            c = findClass(name);
        }
    }
    if (resolve) {
    resolveClass(c);
    }
    return c;
}
 那麼Set它父類的方式有兩種。public class MyClassLoader extends ClassLoader{
    public MyClassLoader(){
        super(MyClassLoader.class.getClassLoader());
    }
}或者public class MyClassLoader extends ClassLoader{
    public MyClassLoader(){
        super(getClass().getClassLoader());
    }
} 這裡是首選第一種。 因為getClass()是在建構函式內部得方法,所以必須要有建構函式代碼存在,但是如果不存在,那就找父類得classloader 一直找啊找,直至找到到findBootstrapClass, 如果它也不存在得話,那時候findClass()方法會被調用執行。。到那時候會報一個ClassNotFoundException。  來看看findClass()得代碼    protected Class<?> findClass(String name)
        throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    } 在findClass() 方法內 class loader要取得到得位元組碼(就是.class檔案裡得內容),然而不不一定就是.class檔案, 這些位元組碼可以來自本地,也可以是系統,網路(藉著這個你可以理解一下Cobra,RMI),也可以是用BCEL(Apache一個基於位元組碼得一個引擎庫) ...等等。 一但位元組碼找到了。那時候就開始執行defineClass()方法。那時候會定義出一個類的執行個體來。
 
如果有兩個ClassLoader 執行個體化兩個相同得代碼,defineClass()定義得兩個類也是不同得。詳細請看(Java language specification)

    protected Class<?> findClass(String name)
        throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    } 在findClass() 方法內 class loader要取得到得位元組碼(就是.class檔案裡得內容),然而不不一定就是.class檔案, 這些位元組碼可以來自本地,也可以是系統,網路(藉著這個你可以理解一下Cobra,RMI),也可以是用BCEL(Apache一個基於位元組碼得一個引擎庫) ...等等。 一但位元組碼找到了。那時候就開始執行defineClass()方法。那時候會定義出一個類的執行個體來。
 
如果有兩個ClassLoader 執行個體化兩個相同得代碼,defineClass()定義得兩個類也是不同得。詳細請看(Java language specification)    展示了一個MyMainclass.class如何裝載執行。(由多個classLoader載入同一個Target.class),----和我們想象中有差別得是,它首先是由於BootStarpClassLoader載入得。根據上面得解析,既然兩個classLoader()載入Target.class得位元組碼 ,那defineClass()就會產品兩個class得定義得。 所以很容易得出結論Target target3 = (Target) target2; 是不能被執行地。
    具體請看Inside Class Loaders(Andreas Schaefer)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.