java类加载器,java类加载
java类加载器,java类加载
类加载器:
java虚拟机中可以安装多个类加载,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap(内嵌在java虚拟机中由C++编写),ExtClassLoader,AppClassLoad
类加载器也是java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是java类,这正是BootStrap.
java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其指定一个父级类装载器对象或者采用系统类装载器为其父级类加载。
类加载器之间的父子关系和管辖范围:
BootStrp------>JRE/lib/rt.jar(这是预先载入好的)
ExtClassLoader---------->JRE/lib/ext/*.jar(这也是预先载入好的)
AppClassLoader---------->CLASSPATH指定的所有jar或目录。(仅仅声明不会载入,当用时才会在入)
类加载器的委托机制:
当java虚拟机要加载一个类时,到底派出哪个类加载器加载呢?
1.首先当前线程的类加载器去加载线程中的第一个类。
2.如果类A中引用了类B,java虚拟机将使用加载类A的类加载器来加载类B.
3.还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。
1.当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛出ClassNotFoundException,不是再去找发起者类
类加载器的儿子,因为没有getChild方法,即使有,那有多个儿子,找哪一个呢?
2.对着类加载器的层次结构图和委托加载原理,解释先去将ClassLoaderTest输出成jre/lib/ext目录下的elva.jar包中后,运行结果为ExtClassLoader的原因。
面试题:能不能自己写个类叫java.lang.System,为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,也就是总是使用爸爸们能找到的类,这样总是使用java系统提供的System.但是我们可以写一个类加载器来加载我们自己写的java.lang.System类。
引用http://www.iteye.com/topic/703842的部分代码
ClassLoader的loadClass代码:
Java代码- protected synchronized Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- // First, check if the class has already been loaded
- //类是否被加载过
- Class c = findLoadedClass(name);
- if (c == null) {
- try {
- if (parent != null) {
- //到parentclassloader中去查找(像这个parent还有parent递归方式进行查找)
- c = parent.loadClass(name, false);
- } else {
- //启动类加载器进行加载
- c = findBootstrapClass0(name);
- }
- } catch (ClassNotFoundException e) {
- // If still not found, then invoke findClass in order
- // to find the class.
- //当一直都没有找到时,启动当前类的findClass进行查找
- //这个通常也是我们扩展的地方
- c = findClass(name);
- }
- }
- if (resolve) {
- resolveClass(c);
- }
- return c;
- }
相关文章
- 暂无相关文章
用户点评