ClassLoader obj = loader_3.class.getClassLoader();//sun.misc.Launcher$AppClassLoader@14dad5dcSystem.out.println(obj.toString());//sun.misc.Launcher$ExtClassLoader@1b6d3586System.out.println(obj.getParent().toString());//getParent***//nullSystem.out.println(obj.getParent().getParent().toString());-----------------------------------------------------------------------------------@CallerSensitivepublicfinalClassLoadergetParent(){(){if(parent ==null)//父加载器为空直接返回空returnnull;SecurityManager sm =System.getSecurityManager();if(sm !=null){// Check access to the parent class loader// If the caller's class loader is same as this class loader,// permission check is performed.checkClassLoaderPermission(parent,Reflection.getCallerClass());}//不为空直接返回父加载器return parent;}-------------------------------parent是在哪个位置赋值呢???
--------AppClassLoader----Launcher----------------------------------------------staticclassAppClassLoaderextendsURLClassLoader{finalURLClassPath ucp =SharedSecrets.getJavaNetAccess().getURLClassPath(this);//var0:父publicstaticClassLoadergetAppClassLoader(finalClassLoader var0)throwsIOException{finalString var1 =System.getProperty("java.class.path");finalFile[] var2 = var1 ==null?newFile[0]:Launcher.getClassPath(var1);return(ClassLoader)AccessController.doPrivileged(newPrivilegedAction<Launcher.AppClassLoader>(){publicLauncher.AppClassLoaderrun(){
URL[] var1x = var1 ==null?new URL[0]:Launcher.pathToURLs(var2);//创建app加载器,在构造函数中this.parent=parent ****returnnewLauncher.AppClassLoader(var1x, var0);}});}AppClassLoader(URL[] var1,ClassLoader var2){super(var1, var2,Launcher.factory);//***this.ucp.initLookupCache(this);}}----------------------------------------super//***----------------------------------------protectedClassLoader(ClassLoader parent){this(checkCreateClassLoader(), parent);//***}----------------------------------------privateClassLoader(Void unused,ClassLoader parent){this.parent = parent;//parent就在此处赋值if(ParallelLoaders.isRegistered(this.getClass())){
parallelLockMap =newConcurrentHashMap<>();
package2certs =newConcurrentHashMap<>();
domains =Collections.synchronizedSet(newHashSet<ProtectionDomain>());
assertionLock =newObject();}else{// no finer-grained lock; lock on the classloader instance
parallelLockMap =null;
package2certs =newHashtable<>();
domains =newHashSet<>();
assertionLock =this;}}---------------ExtClassLoader----------------------------------staticclassExtClassLoaderextendsURLClassLoader{//没有传父publicstaticLauncher.ExtClassLoadergetExtClassLoader()throwsIOException{finalFile[] var0 =getExtDirs();try{return(Launcher.ExtClassLoader)AccessController.doPrivileged(newPrivilegedExceptionAction<Launcher.ExtClassLoader>(){publicLauncher.ExtClassLoaderrun()throwsIOException{int var1 = var0.length;for(int var2 =0; var2 < var1;++var2){MetaIndex.registerDirectory(var0[var2]);}//与上面的追踪相同,传一个空值,parent=nullreturnnewLauncher.ExtClassLoader(var0);}});}catch(PrivilegedActionException var2){throw(IOException)var2.getException();}}
类加载过程
//分析类加载过程 ***Class c = obj.loadClass("com.yc.classloader1.Person");System.out.println(c);-------------------------------------------------------------------------------publicClass<?>loadClass(String name)throwsClassNotFoundException{returnloadClass(name,false);//***//false:文件加载到虚拟机,该引用形成没有}-------------------------------------------------------------------------------protectedClass<?>loadClass(String name,boolean resolve)throwsClassNotFoundException{synchronized(getClassLoadingLock(name)){// First, check if the class has already been loaded//先去虚拟机中找一个有没有该名字,判断当前类是否已经加载 ***Class<?> c =findLoadedClass(name);if(c ==null){//当前类没有被加载long t0 =System.nanoTime();try{if(parent !=null){//当前类的父加载器是否为空//调用extclassLoder的loadClass----->还是该方法 递归
c = parent.loadClass(name,false);}else{//通过根加载器来加载这个类 ***
c =findBootstrapClassOrNull(name);}}catch(ClassNotFoundException e){// ClassNotFoundException thrown if class not found// from the non-null parent class loader}//findBootstrapClassOrNull根加载器没有加载到if(c ==null){// If still not found, then invoke findClass in order// to find the class.long t1 =System.nanoTime();//父类构造URLClassLoader中实现findClass方法,拿得到c就是Class,否则null--->递归
c =findClass(name);//*****// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}//已经加载if(resolve){//resolve:falseresolveClass(c);//在方法区中建立引用***}return c;}}--------------------------------------------------------protectedfinalClass<?>findLoadedClass(String name){if(!checkName(name))returnnull;returnfindLoadedClass0(name);//***}--------------------------------------------------------//本地方法 用C++去虚拟机中找虚拟机中是否已经加载privatenativefinalClass<?>findLoadedClass0(String name);------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/**
* Links the specified class. This (misleadingly named) method may be
连接指定的类,类加载器可能会使用该方法来加载一个类,。如果该类c已经被连接过
* used by a class loader to link a class. If the class <tt>c</tt> has
那么这个方法只需要返回,否则没有被连接过那这个类就要连接一下(在堆区做一个引用)
* already been linked, then this method simply returns. Otherwise, the
* class is linked as described in the "Execution" chapter of
* <cite>The Java™ Language Specification</cite>.
*
* @param c
* The class to link
*
* @throws NullPointerException
* If <tt>c</tt> is <tt>null</tt>.
*
* @see #defineClass(String, byte[], int, int)
*/protectedfinalvoidresolveClass(Class<?> c){resolveClass0(c);//****}--------------------------------------------------------privatenativevoidresolveClass0(Class<?> c);------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------privateClass<?>findBootstrapClassOrNull(String name){//检查名字是否合法if(!checkName(name))returnnull;returnfindBootstrapClass(name);}--------------------------------------------------------// return null if not foundprivatenativeClass<?>findBootstrapClass(String name);------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------protectedClass<?>findClass(finalString name)throwsClassNotFoundException{finalClass<?> result;try{
result =AccessController.doPrivileged(newPrivilegedExceptionAction<Class<?>>(){publicClass<?>run()throwsClassNotFoundException{//拼接路径String path = name.replace('.','/').concat(".class");//加载资源,文件加载器Resource res = ucp.getResource(path,false);if(res !=null){try{//使用反射,返回Class***returndefineClass(name, res);}catch(IOException e){thrownewClassNotFoundException(name, e);}}else{returnnull;}}}, acc);}catch(java.security.PrivilegedActionException pae){throw(ClassNotFoundException) pae.getException();}if(result ==null){thrownewClassNotFoundException(name);}return result;}-------------------------------------------------------------privateClass<?>defineClass(String name,Resource res)throwsIOException{long t0 =System.nanoTime();int i = name.lastIndexOf('.');//资源路径 classpath(target/classes)URL url = res.getCodeSourceURL();if(i !=-1){String pkgname = name.substring(0, i);// Check if package already loaded.Manifest man = res.getManifest();definePackageInternal(pkgname, man, url);}// Now read the class bytes and define the classjava.nio.ByteBuffer bb = res.getByteBuffer();if(bb !=null){// Use (direct) ByteBuffer:CodeSigner[] signers = res.getCodeSigners();CodeSource cs =newCodeSource(url, signers);sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);returndefineClass(name, bb, cs);}else{//获取字节码byte[] b = res.getBytes();// must read certificates AFTER reading bytes.CodeSigner[] signers = res.getCodeSigners();CodeSource cs =newCodeSource(url, signers);sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);returndefineClass(name, b,0, b.length, cs);}//作用:加载字节码 //最终返回Class}