自定义类加载器在复杂类加载情况下的运行分析
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("com.erwa.jvm.MySample");
System.out.println(clazz.hashCode());
// 如果注释掉该行,那么并不会实例化MySample对象,即MySample构造方法不会被调用
//因此不会实例化MyCat对象,即没有对MyCat进行主动使用。这里就不会加载MyCat的CLass
Object object = clazz.newInstance();
}
}
> 输出结果
> Task :MyTest17.main()
2018699554
MySample is loaded by : sun.misc.Launcher$AppClassLoader@659e0bfd
MyCat is loaded by : sun.misc.Launcher$AppClassLoader@659e0bfd
这个例子有多种情况,结果是不同的。
ClassPath 中删除 MySample
ClassPath 中删除 MyCat
ClassPath 中删除 MyCat MySample
》 总体来说,就是命名空间的概念。
- 子加载器所加载的类能够访问父加载器所加载的类
- 父加载器加载的类无法访问子加载器所加载的类
2020年02月10日21:36:38
对于类加载器,具体是从哪个地方加载的?
系统类加载器:sun.boot.class.path (加载系统的包,包含jdk核心库里的类)
扩展类加载器:java.ext.dirs(加载扩展jar包中的类)
应用类加载器:java.class.path(加载你编写的类,编译后的类)