2014-09-21 105 views
2

這是一個使用類加載器的例子,您可以看到輸出。爲什麼objobj2的類加載器不同?我知道'父類加載器'的想法。JVM中的類加載器

public class jvm_77{ 

    public static void main(String[] args) throws Exception{ 
     ClassLoader myLoader = new ClassLoader(){ 

      public Class<?> loadClass(String name) throws ClassNotFoundException{ 
       try 
       { 
        String fileName = name.substring(name.lastIndexOf(".")+1)+".class"; 
        InputStream is = getClass().getResourceAsStream(fileName); 
        if(is == null) 
        { 
         return super.loadClass(name); 
        } 
        byte[] b = new byte[is.available()]; 
        is.read(b); 
        return defineClass(name,b,0,b.length); 
       }catch(IOException e) 
       { 
        throw new ClassNotFoundException(name); 
       } 
      } 

     }; 

     Object obj = myLoader.loadClass("Chapter7_ClassLoader.jvm_77").newInstance(); 
     jvm_77 obj2 = new jvm_77(); 

     System.out.println(obj.getClass().getClassLoader()); //[email protected] 
     System.out.println(obj2.getClass().getClassLoader()); //[email protected] 

     System.out.println(obj.equals(obj2));//false 
     System.out.println(obj instanceof Chapter7_ClassLoader.jvm_77);//false 
     System.out.println(obj2 instanceof Chapter7_ClassLoader.jvm_77);//true 
    } 

} 

回答

2

爲什麼OBJ的類加載器和obj2的類裝入器有什麼不同?

該行創建了標準類加載器加載的jvm_77類的實例。

jvm_77 obj2 = new jvm_77(); 

此行是創建位於由您定製的ClassLoader的jvm_77類的一個實例。

Object obj = myLoader.loadClass("Chapter7_ClassLoader.jvm_77").newInstance(); 

所以基本上,你問也是爲什麼兩種方法不會給你同樣的Class對象。而這個問題的答案是,你已經在你的類加載器來實現loadClass方式:

  • loadClass方法的默認行爲是:

    1. 嘗試父類加載器
    2. 如果失敗,檢查我們是否已經加載類
    3. 如果失敗,找到資源並加載類。
  • 你的類加載器的loadClass方法做到這一點:

    1. 試圖尋找資源
    2. 如果資源查找成功,加載資源
    3. 如果資源查找失敗,請嘗試父類加載器。

顯然,你的定製ClassLoader是要嘗試定義一個新的類...如果可能的話。顯然,它是成功的。


總之,類加載器的,因爲你實現loadClass方法的方法是在不同的輸出。