类加载器 一、定义:简单说,就是加载类的工具(当出现一个类时,并用到时,java虚拟机首先加类字节码加载进内存,通常字节码的原始信息放在硬盘上的classpash指定目录下)。 作用:将.class文件中的内容加载到内存进行处理,处理的结果就是字节码。 二、默认类加载器: Java虚拟机中可安装多个类加载器,系统默认有三个主要的: Bootstrap:顶级类加载器,路径:JRE/lib/rt.jar(它是嵌套在java虚拟机内核中的,已启动即出现在虚拟机中,是C++写的一段二进制代码,不能通过java程序获得其名字,获得的知识null) ExtClassLoader:路径:JRE/lib/ext/*.jar AppClassLoader:路径:classpash指定的所有jar或目录。 注:java虚拟机中的所有类加载器采用父子关系的树形结构进行组织,在实例化每个类加载器对象或默认采用系统类加载器作为其父级类加载器。 可以自定义类加载器,路径:自己指定的特殊目录。 三、类加载器的委托机制(当加载一个类时,派哪个类加载器去加载) 方法:1、当前线程的类加载器去加载线程中的第一个类 2、如果类A中引用了类B,java虚拟机将使用加载类A的类加载器去加载类B 3、还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。 注:每个类加载器加载类时,又先委托给其上一级类加载器。 当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了则抛出ClassNotFoundException,不是再去找发起者类加载器的儿子,因为其下可能有很多的儿子。 四、类加载器的委托模式: 每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类加载器去加载类,这就是类加载器的委托机制。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,才一级级回到子孙类装载器去进行真正的加载。当回退到最初的类加载器时,如果它自己也不能完成类的加载,将抛出ClassNotFoundException异常。 五、自定义类加载器: 1、继承ClassLoader 2、loadClass方法(直接继承)findClass方法(覆写) defineClass方法 六、一个类加载器的高级问题分析 父级类加载器加载的类无法引用只能被子级类加载器加载的类。 public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter();// it out is explorer ClassLoader loader = this.getClass().getClassLoader(); while(loader != null) { System.out.println(loader.getClass().getName()); loader = loader.getParent(); } out.close(); } } 把MyServlet.class文件打jar包,放到ext目录中,重启tomcat,发现找不到HttpServlet的错误。 把Servlet.jar也放到ext目录中,问题解决了,打印的结果是ExtclassLoader。
|