美文网首页
java ClassLoader 双亲委派

java ClassLoader 双亲委派

作者: LiuJP | 来源:发表于2019-01-15 10:16 被阅读0次

能自己练习一次就能更深入的了解ClassLoader
https://blog.csdn.net/briblue/article/details/54973413

public class ClassLoaderTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ClassLoader cl = ClassLoaderTest.class.getClassLoader();

        // cl = int.class.getClassLoader();
        //
        // System.out.println("ClassLoader is:"+cl.toString());
        System.out.println("ClassLoader is:" + cl.toString());
        System.out.println("ClassLoader\'s parent is:" + cl.getParent().toString());
        System.out.println("ClassLoader\'s grand father is:" + cl.getParent().getParent().toString());
    }
}

运行结果:

ClassLoader is:sun.misc.Launcher$AppClassLoader@4e25154f
ClassLoader's parent is:sun.misc.Launcher$ExtClassLoader@33909752
Exception in thread "main" java.lang.NullPointerException
    at ClassLoaderTest.main(ClassLoaderTest.java:14)
// ExtClassLoader 没有父类ClassLoader

Class 中的final ClassLoader 是jvm 虚拟机初始化时候

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
    /*
     * Private constructor. Only the Java Virtual Machine creates Class objects.
     * This constructor is not used and prevents the default constructor being
     * generated.
     */
    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }
}

ClassLoader.java

public abstract class ClassLoader {

// The parent class loader for delegation
// Note: VM hardcoded the offset of this field, thus all new fields
// must be added *after* it.
private final ClassLoader parent;
// The class loader for the system
    // @GuardedBy("ClassLoader.class")
private static ClassLoader scl;

private ClassLoader(Void unused, ClassLoader parent) {
    this.parent = parent;
    ...
}
protected ClassLoader(ClassLoader parent) {
    this(checkCreateClassLoader(), parent);
}
protected ClassLoader() {
    this(checkCreateClassLoader(), getSystemClassLoader());
}
public final ClassLoader getParent() {
    if (parent == null)
        return null;
    return parent;
}
public static ClassLoader getSystemClassLoader() {
    initSystemClassLoader();
    if (scl == null) {
        return null;
    }
    return scl;
}

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;
            //通过Launcher获取ClassLoader
            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;
    }
}
}

我们可以看到getParent()实际上返回的就是一个ClassLoader对象parent,parent的赋值是在ClassLoader对象的构造方法中,它有两个情况:
1. 由外部类创建ClassLoader时直接指定一个ClassLoader为parent。
2. 由getSystemClassLoader()方法生成,也就是在sun.misc.Laucher通过getClassLoader()获取,也就是AppClassLoader。直白的说,一个ClassLoader创建时如果没有指定parent,那么它的parent默认就是AppClassLoader。

我们主要研究的是ExtClassLoader与AppClassLoader的parent的来源,正好它们与Launcher类有关,我们上面已经粘贴过Launcher的部分代码

public class Launcher {
    private static Launcher launcher = new Launcher();
    private static String bootClassPath =
        System.getProperty("sun.boot.class.path");

    public static Launcher getLauncher() {
        return launcher;
    }

    private ClassLoader loader;

    public Launcher() {
        // Create the extension class loader
        ClassLoader extcl;
        try {
            extcl = ExtClassLoader.getExtClassLoader();
        } catch (IOException e) {
            throw new InternalError(
                "Could not create extension class loader", e);
        }

        // Now create the class loader to use to launch the application
        try {
            loader = AppClassLoader.getAppClassLoader(extcl);
        } catch (IOException e) {
            throw new InternalError(
                "Could not create application class loader", e);
        }

        //设置AppClassLoader为线程上下文类加载器,这个文章后面部分讲解
        Thread.currentThread().setContextClassLoader(loader);
    }

    /*
     * Returns the class loader used to launch the main application.
     */
    public ClassLoader getClassLoader() {
        return loader;
    }
    /*
     * The class loader used for loading installed extensions.
     */
    static class ExtClassLoader extends URLClassLoader {}

/**
     * The class loader used for loading from java.class.path.
     * runs in a restricted security context.
     */
    static class AppClassLoader extends URLClassLoader {}

双亲委托

这里写图片描述

怎么绕过双亲委派?

关注微信公众号

相关文章

  • sandBox源码分析之ClassLoader

    提起classLoader,就不由自主想起了java classLoader的双亲委派模型,那么到底什么是双亲委派...

  • 为什么说SPI打破双亲委派机制

    简单介绍ClassLoader的双亲委派机制: java类通过Classloader加载,Classloader之...

  • 简单了解什么是双亲委派机制?

    什么是双亲委派机制 了解双亲委派,需要先了解下JAVA的类加载器ClassLoader,java的类加载器主要有以...

  • Java ClassLoader双亲委派

    双亲委派这个名字感觉定义可读性不太高,其实就是一个自下而上、自上而下的加载过程。 那么为什么需要采用双亲委派,主要...

  • java ClassLoader 双亲委派

    能自己练习一次就能更深入的了解ClassLoaderhttps://blog.csdn.net/briblue/a...

  • JAVA ClassLoader双亲委派

    双亲委派机制的意义:当一个类需要被加载的时候,需要通过一个类的全限定名来获取定义此类的二进制字节流,而这个动作由C...

  • 安卓classloader浅析

    classloader 是采用双亲委派的方式加载所需要的类。 双亲委派:从classloader的源码分析,在加载...

  • 【Android】Android中的类加载

    前文:【Java】ClassLoader与双亲委派机制[https://www.jianshu.com/p/684...

  • 类加载机制

    一:双亲委派机制ClassLoader#loadClass(ClassLoader源码[https://www.j...

  • JAVA类加载机制

    jvm之java类加载机制和类加载器(ClassLoader)的详解java类加载机制:全盘负责、双亲委派、缓存机...

网友评论

      本文标题:java ClassLoader 双亲委派

      本文链接:https://www.haomeiwen.com/subject/bkuedqtx.html