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为用户类返回了这个类。
这是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); } }
答案 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的实例。 所以这里没有什么神秘的东西。