java如何识别类加载器?

时间:2016-12-29 15:14:24

标签: java classloader

sun.misc.Launcher.AppClassLoader - 是默认的系统类加载器。

用户类由此类加载器加载。

e.g:

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. 它是如何运作的?
  3. 这是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);
        }
    }
    

1 个答案:

答案 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/share/vm/classfile/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的实例。 所以这里没有什么神秘的东西。