19-自定义类加载器在复杂类加载情况下的运行分析

自定义类加载器在复杂类加载情况下的运行分析

  • 实例:

    public class MyCat {
        public MyCat(){
            System.out.println("MyCat is loaded by:"+this.getClass().getClassLoader());
        }
    }
    
    public class MySample {
       public MySample() {
          System.out.println("MySample is loaded by :" +this.getClass().getClassLoader());
          new MyCat();  //【重要】
       }
    }
    
    public class MyTest17 {
        public static void main(String[] args) throws Exception {
            MyTest16 loader1 = new MyTest16("loader1");
            Class<?> clazz = loader1.loadClass("Jvm.MySample");  //先加载
            System.out.println("class : " + clazz.hashCode());
            //如果注释掉该行,那么并不会实例化MySample对象,即MySample构造方法不会被调用
            //因此不会实例化MyCat对象,即没有对Mycat进行主动使用,这里就不会加载MyCat Class
            ★ Object object = clazz.newInstance();  //再创建实例
        }
    }
    (1)在注释掉★行的时候:
    	此时 Class<?> clazz = loader1.loadClass("Jvm.MySample"); 会加载MySample、MyCat,虽然在MySample的构造方法中有new Cat(),但是这两个类并没有被初始化。这里有一个预加载的概念以及该节下面最后一句的踪迹。
    	运行结果:
       	class : 325040804
    (2)在放开★行的时候:
    	运行结果:
    	class : 325040804
          MySample is loaded by :sun.misc.Launcher$AppClassLoader@18b4aac2
          MyCat is loaded by:sun.misc.Launcher$AppClassLoader@18b4aac2
    
    • 结果分析:

      • class : 325040804 由clazz.hashCode()输出,说明类被加载
      • 而下面两行,纯属是因为clazz.newInstance()实例化了方法,调用构造方法打印出来的,两个类是否被加载进一步分析—>
    • 注释掉 Object object = clazz.newInstance();, VM options 配置上 -XX:+TraceClassLoading

      • 看结果:(MyCat没有被加载!!!)

在这里插入图片描述

- **MyCat是否被加载,并不是取决于是否被主动使用!**这里可以回顾 “**主动加载**” 和 "**预加载**"。
发布了25 篇原创文章 · 获赞 0 · 访问量 1454

猜你喜欢

转载自blog.csdn.net/qq_40574305/article/details/104793401