2016-12-29 42 views
-2

sun.misc.Launcher.AppClassLoader - 是默認的System Class Loader。java如何識別類加載器?

這個類加載器加載用戶類。

例如爲:

public static void main(String args[]) throws Exception { 
    A a = new A(); 
    System.out.println(a.getClass().getClassLoader()); 
} 

返回sun.misc.Launcher $ AppClassLoader。

類A由sun.misc.Launcher.AppClassLoader.loadClass(var1,var2)方法加載。 Java會觸發它隱式加載這個類。

但是,我沒有在上述方法中找到加載邏輯。 通過它的代碼,它似乎將類加載委託給父類加載器。但在這種情況下,必須返回父類加載器而不是AppClassLoader。

再一次,通過這種方法,這個類看起來並沒有被這個類加載器加載,但是java爲用戶類正好返回了這個類。

  1. 爲什麼?
  2. 它是如何工作的?

這是反編譯sun.misc.Launcher.AppClassLoader的方法:

public Class<?> loadClass(String var1, boolean var2) throws ClassNotFoundException { 
    int var3 = var1.lastIndexOf(46); 
    if(var3 != -1) { 
     SecurityManager var4 = System.getSecurityManager(); 
     if(var4 != null) { 
      var4.checkPackageAccess(var1.substring(0, var3)); 
     } 
    } 

    if(this.ucp.knownToNotExist(var1)) { 
     Class var5 = this.findLoadedClass(var1); 
     if(var5 != null) { 
      if(var2) { 
       this.resolveClass(var5); 
      } 

      return var5; 
     } else { 
      throw new ClassNotFoundException(var1); 
     } 
    } else { 
     return super.loadClass(var1, var2); 
    } 
} 
+3

我還是不明白你在問什麼。 –

+0

我不明白你的問題...但嘗試看看這裏http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html也許它會幫你一點點。關於你的編輯,你不明白這種方法的哪一部分? – Hrabosch

+0

感謝您提供的文章。它作爲基本信息很好,但不能回答我的問題。我不明白在「爲虛擬機定義類」部分的哪個部分。此方法並不真正加載類,而是將其進一步委託給父類加載器。 –

回答

1

這裏上課的時候是採取的一例的主要線程堆棧跟蹤A加載:

[native] java.lang.ClassLoader.defineClass1() <= this points to Laucher$AppClassLoader here 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:764) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) 
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362) 
    at java.security.AccessController.doPrivileged(AccessController.java:-1) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    - locked <0x1f4> (a java.lang.Object) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at com.example.Main.main(Main.java:5) 

然後在一些準備工作之後在本地代碼中解析/定義發生在 /src/sh是/ VM /類文件/ classFileParser.cpp:

instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, 
                Handle class_loader, 
                Handle protection_domain, 
                KlassHandle host_klass, 
                GrowableArray<Handle>* cp_patches, 
                TempNewSymbol& parsed_name, 
                bool verify, 
                TRAPS) { 
    // ... lots of code here 
    this_klass->set_class_loader(class_loader()); 
    // ... and here 
} 

其中CLASS_LOADER參數是處理對Laucher $ AppClassLoader的實例。 所以這裏沒有什麼神祕的東西。