美文网首页Java 杂谈
深入理解JVM(一)类加载器部分:双亲委派模型

深入理解JVM(一)类加载器部分:双亲委派模型

作者: 利伊奥克儿 | 来源:发表于2019-06-03 17:53 被阅读0次

    类加载器的父亲委托机制

    • 在父亲委托机制中,各个类加载器按照父子关系形成了树形结构,除了根类加载器之外,其余的类加载器都有且只有一个父加载器。

    先让最顶层可以加在的父加载器加栽(所有可加载的加载器中,处于最顶层的那一个加载器加载,如果都不能加载,则失败)

    -Bootstrap ClassLoader 启动类加载器

    $JAVA_HOME中jre/lib/rt.jar里所有的class,由c++实现,不是ClassLoader的子类

    -Extension ClassLoader 扩展类加载器

    负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中的jre/lib/*.jar或者-Djava.ext.dirs指定目录下的jar包

    • App ClassLoader 系统类加载器
    • 负责加载classpath中指定的jar包及其目录中的class

    成功加载类的加载器叫做定义类加载器

    所有能够成功返回Clas对象引用的类加载器叫做初始类加载器(包括定义累加载器)

    eg1:
    public class MyTest7 {
        public static void main(String[] args)throws Exception {
            Class<?> clazz=Class.forName("java.lang.String");
            System.out.println(clazz.getClassLoader());
    
            Class<?> clazzc=Class.forName("com.aaa.test.c");
            System.out.println(clazzc.getClassLoader());
        }
    }
    class c{
    
    }
    //输出结果:
    null
    sun.misc.Launcher$AppClassLoader@18b4aac2
    
    

    不同类加载器作用和加载器动作分析

    • 获取一个类的父加载器
    public class MyTest13 {
        public static void main(String[] args) {
            ClassLoader classLoader=ClassLoader.getSystemClassLoader();
            System.out.println(classLoader);
            while(classLoader!=null){
                classLoader=classLoader.getParent();
                System.out.println(classLoader);
            }
        }
    }
    
    //输出结果:
    sun.misc.Launcher$AppClassLoader@18b4aac2
    sun.misc.Launcher$ExtClassLoader@512ddf17
    null
        
    
    • 获取资源路径
    /**
     * @author lillcol
     * 2019/5/22-17:09
     */
    public class MyTEST14 {
        public static void main(String[] args) throws IOException {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            System.out.println(classLoader);
    
            String resourceName = "com/aaa/test/MyTest13.class";
            Enumeration<URL> urls = classLoader.getResources(resourceName);
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                System.out.println(url);
            }
        }
    }
    
    //输出结果:
    sun.misc.Launcher$AppClassLoader@18b4aac2
    file:/E:/IdeaProjects/AAAE2E2/target/scala-2.11/classes/com/aaa/test/MyTest13.class
    
    • 几种加载器的获取方法
    /**
     * @author lillcol
     * 2019/5/22-17:09
     */
    public class MyTEST14 {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
    
            Class<?> clazz=Class.forName("com.aaa.test.MyTEST14");
            ClassLoader classLoader1 = clazz.getClassLoader(); //获得当前类的ClassLoader
            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); //获得当前线程上下文的ClassLoader
            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); //获得系统的ClassLoader
            System.out.println(classLoader1);
            System.out.println(contextClassLoader);
            System.out.println(systemClassLoader);
        }
    }
    //输出结果:
    sun.misc.Launcher$AppClassLoader@18b4aac2
    sun.misc.Launcher$AppClassLoader@18b4aac2
    sun.misc.Launcher$AppClassLoader@18b4aac2
    
    

    用户自定义的类、启动类由AppClassLoader加载

    String类由根类加载器加载

    /**
     * @author lillcol
     * 2019/5/22-17:09
     */
    public class MyTEST14 {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
    
            Class<?> clazz=MyTEST14.class;
            System.out.println(clazz.getClassLoader());
            System.out.println("----------");
            Class<?> clazz1=String.class;
            System.out.println(clazz1.getClassLoader());
        }
    }
    //输出结果:
    sun.misc.Launcher$AppClassLoader@18b4aac2
    ----------
    null
    
    

    本文为学习张龙老师深入理解JVM的笔记与心得,转载请注明出处!!!

    相关文章

      网友评论

        本文标题:深入理解JVM(一)类加载器部分:双亲委派模型

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