研究类加载的目的
- 类加载是类执行的第一步, 研究类加载有助于了解JVM的执行过程,并帮助开发者,采取更有效的措施,配合程序执行。
- 能够让程序动态的控制加载类(热部署)。提高程序的灵活性和适应性。
java类加载过程
- 寻找jre目录,寻找jvm.dll 初始化JVM;
- 产生一个BootStrap Loader;
- BootStrap Loader 自动加载Extend Loader 并将父Loader设置为BootStrap Loader
- BootStrap Loader 自动加载AppClass Loader,并将其父Loader设置为Extend Loader
- 最后有AppClass Loader 加载类
类加载器各自的搜索目录
- BootStrap Loader加载System.getProperty(“sun.boot.class.path”)所指定的路径或jar;
- Extend Loader 加载System.getProperty(“java.ext.dirs”)所指定的路径或jar。在使用Java运行程序时,也可以指定其搜索路径,例如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld;
- AppClass Loader加载System.getProperty(“java.class.path”)所指定的路径或jar,在使用Java运行程序时,也可以加上-cp来覆盖原有的Classpath设置,例如: java -cp ./lavasoft/classes HelloWorld;
- ExtClassLoader和AppClassLoader会在JVM启动以后,会在JVM中保存一份,并且在程序中无法改变其搜索路径,如果想在运行时从其他的搜索路径加载类,就要产生新的加载类。
类加载器的特点
- 运行一个程序时总是有AppClassLoader加载指定的类;
- 加载类时,每个类加载器总是首先将家在任务交给父类加载器,若父类加载器加载不到,自己才去加载;
- BootStrap Loader时最顶级的加载器,其父加载器为null;
类加载器的获取
Test test=new Test("11j")
Class<? extends Test> testClass = test.getClass()
ClassLoader classLoader = testClass.getClassLoader()
System.out.println(classLoader)
System.out.println(classLoader.getParent())
System.out.println(classLoader.getParent().getParent())
类的加载
- 命令行启动应用的时候由JVM加载;
- 通过Class.forName()动态加载;
- 通过ClassLoader.loadClass()方法动态加载;
自定义ClassLoader
总结
- 同一个ClassLoader加载的类文件只有一个class实例,但如果同一个类文件被不同的ClassLoder载入, 则会有两个类加载器但是这个两个类加载不能够用相同的父类加载器。
原文地址