ClassLoader类加载机制

       

                                             ExclassLoader                     java

 

                                      AppClassLoaderapi

 

 上图类关系出自sun.misc.Launcher类,能够看出ExclassLoader与 AppClassLoader都继承与URLClassLoader,而非继承Bootstrap ClassLoaderapp

public class MyAppClassLoader {

    private static class Test {
        Test() {
            System.out.println("Hello World!");
        }
    }

    Launcher launcher = new Launcher();


    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader classLoader = MyAppClassLoader.class.getClassLoader();
        System.out.println(classLoader);
        System.out.println(classLoader.getParent());
        System.out.println(classLoader.getParent().getParent());
    }
}
"C:\Program Files\Java\jdk1.7.0_80\bin\java" "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=61577:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_80\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\rt.jar;D:\ideaprojects\NewCoderTest\out\production\NewCoderTest" MyAppClassLoader
sun.misc.Launcher$AppClassLoader@7b7035c6
sun.misc.Launcher$ExtClassLoader@3da997a
null

Process finished with exit code 0

 ExclassLoader与 AppClassLoader都继承与URLClassLoade,而URLClassLoade实现抽象类ClassLoader。ide

 

分析Launcher源码oop

Launcher.classthis

public Launcher() {
        Launcher.ExtClassLoader var1;
        try {
//先建立ExtClassLoader var1 = Launcher.ExtClassLoader.getExtClassLoader(); } catch (IOException var10) { throw new InternalError("Could not create extension class loader"); } try {
//由ExtClassLoader再去建立它的子类加载器,再讲将该类加载器置为Launcher的默认类加载器 this.loader = Launcher.AppClassLoader.getAppClassLoader(var1); } catch (IOException var9) { throw new InternalError("Could not create application class loader"); } Thread.currentThread().setContextClassLoader(this.loader); String var2 = System.getProperty("java.security.manager"); if(var2 != null) { SecurityManager var3 = null; if(!"".equals(var2) && !"default".equals(var2)) { try { var3 = (SecurityManager)this.loader.loadClass(var2).newInstance(); } catch (IllegalAccessException var5) { ; } catch (InstantiationException var6) { ; } catch (ClassNotFoundException var7) { ; } catch (ClassCastException var8) { ; } } else { var3 = new SecurityManager(); } if(var3 == null) { throw new InternalError("Could not create SecurityManager: " + var2); } System.setSecurityManager(var3); } }

ClassLoader.classidea


private static synchronized void initSystemClassLoader() { if (!sclSet) { if (scl != null) throw new IllegalStateException("recursive invocation"); sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); if (l != null) { Throwable oops = null; scl = l.getClassLoader(); try { scl = AccessController.doPrivileged( new SystemClassLoaderAction(scl)); } catch (PrivilegedActionException pae) { oops = pae.getCause(); if (oops instanceof InvocationTargetException) { oops = oops.getCause(); } } if (oops != null) { if (oops instanceof Error) { throw (Error) oops; } else { // wrap the exception throw new Error(oops); } } } sclSet = true; } }



 

追踪到最后由该类进行调用 (看注释能够得出,做为默认加载器被调用)
@CallerSensitive
public static ClassLoader getSystemClassLoader() {
    initSystemClassLoader();
    if (scl == null) {
        return null;
    }
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkClassLoaderPermission(scl, Reflection.getCallerClass());
    }
    return scl;
}

  

看ClassLoader.class中的loadClass方法,探究类加载原理spa

    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
//getClassLoadingLock方法,经过类名获取 synchronized (getClassLoadingLock(name)) { // 检查该类是否已经被加载过 Class c = findLoadedClass(name); if (c == null) {
//计时,输出纳秒级别时间 long t0 = System.nanoTime(); try {
//因而可知BootstrapClassLoader并非ExtClassLoader加载器的父加载器,仅仅只是在经过父加载优先行不通的状况下,才会去找BootstrapClassLoader if (parent != null) {
//先查找父类加载器,false表示 c = parent.loadClass(name, false); } else {
//查找BootstrapClass,找不到返回null c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime();
//若是都没找到经过本加载器加载 c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }

 

private final ConcurrentHashMap<String, Object> parallelLockMap;
经过类名,若是paralleLockMap这个ConcurrentHashMap为空,这返回ClassLoader,不然经过putIfAbsent源码能够看到,该方法若是一个HashEntry中可以找到该key对应value值则返回该value,
若是找不到,则返回null,则返回Object
protected Object getClassLoadingLock(String className) {
            Object lock = this;
            if (parallelLockMap != null) {
            Object newLock = new Object();
            //经过putIfAbsent源码能够看到,该方法若是一个HashEntry中可以找到该key对应value值则返回该value,若是不能找到,则返回null,下面会分析ConcurrentHashMap中的该源码
            lock = parallelLockMap.putIfAbsent(className, newLock);
            if (lock == null) {
                lock = newLock;
            }
        }
        return lock;
    }

  

protected final Class<?> findLoadedClass(String name) {
        if (!checkName(name))
            return null;
        return findLoadedClass0(name);
    }
 //native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其余语言(如C和C++)实现的文件中。
private native final Class findLoadedClass0(String name);

  

总结:由上的代码分析能够分析出loadClass加载类的过程,以及对BootstrapClassLoader的误解。3d

相关文章
相关标签/搜索