黑马程序员--类加载器
java类加载器就是将.class文件中的二进制读入到内存中。
java类加载器也是类,它们是由最原始的类加载器加入到java虚拟机中,然后再由他们加载其他的类,而最原始的类加载器就是BootStrap,他不是Java类,是由C++编写的
在java中有三种类加载器:BootStrap(加载系统类,如System),ExtClassloader(加载lib/ext/里的.jar包),AppClassLoader(加载我们自定义的类)
BootStrap是ExtClassLoader的上级,ExtClassLoader是AppClassloader的上级
★这里有一个比较隐藏的问题,如果tomcat中启动,将java类打包成jar包放在jre\lib\ext文件夹中,这样 ExtClassLoader就会加载,如果该类引用的其他类没有打包成jar放在ext文件夹中,这是浏览器就会报错了,必须将该类引用的其他类也打包 才行。
printWriter out这个out是输出在浏览器上的,System.out这是输出在控制台上的
★当需要加载一个类时,首先会选择加载当前线程的类加载器加载该类,其次是选择引用了该类的其他类的类加载器。还可以使用ClassLoader.loadClass()指定使用哪一个加载器
当确定了使用哪一个类加载器时,就比如是AppClassLoader,他首先会委托上级ExtClassLoader加载该 类,ExtClassLoader再委托他的上级BootStrap进行加载,,如果BootStrap这个加载器没有找到,就返回 ExtClassLoader,如果他也没有找到,在返回AppClassLoader,由于AppClassLoader是发起者,如果他也没有找到, 就不会再往下返回了,而是直接返回ClassNotFoundException。
★有个面试题:如果我们自己定义java.lang.System类,会不会被加载,答案是:通常来说是不会
java为了防止我们自己定义系统类,类加载器采用了委托机制,某一个类加载器加载的时候,首先会委托给其上级加载,如果其上级加载成功了,他就不 会加载了,我们自己定义的System首先选择AppClassLoader加载器,他最终会委托给BootStrap加载器,BootStrap会将系 统中的System类加载到虚拟机中,这样AppClassLoader就不会加载我们自己定义的System类了。但是我们也可以自己写一个类加载器, 只要撇开了委托加载机制就可以了。