java类装载器:
java虚拟机使用每一个类的第一件事是就是将这个类的字节码文件加载进来,装载类字节码的工作是由类装载器完成的!当一个类被加载后,java虚拟机将其编译为可执行代码存储在内存中并将索引信息存储进Hashtable中,其索引关键字为与之对应的类名!
java程序中的类本身也是一种事物,他也可以用一个java类来描述,这个特殊的类就是Class,类装载器装载某个类的过程实际上就是创建一个Class的实例对象!
可以用三种方式来创建一个Class类的实例对象:
1)类名.Class 例如:HelloWorld.Class
2) 对象.getClass() 例如:new Date().getClass()
3) Class.forName("类名")例如:Class.forName("java.util.Date")
java类库提供了一个类装载器的基类:java.lang.ClassLoader(抽象类)java虚拟机和程序都使用ClassLoader类的loadClass方法来加载类,真正的类必须是ClassLoader的子类
Class类提供了一个getClassLoder用于返回它所描述的类的类加载器的对象,返回的类型就是ClassLoader
java虚拟机内嵌了一个bootstrap的类装载器它属于java虚拟机的内核,不用类装载器装载,它负责加载java核心包中的类(rt.jar) ExtClassLoder类负责加载%java_home%/jre/lib/ext目录下的jar包,AppClassLoder负责加载应用程序的启动执行类,ExtClassLoder是AppClassLoder的父级类装载器!
如果把相关的jar文件放在%java_home%/jre/lib/ext目录下就不需要在classpath中配置了!
类的装载器的委托模式:先由类的父级装载类加载,如果没有找到,继续向上由父级的父级找,一直到bootstrap如果还没找到,则由子类调用findClass()方法来加载类!
知道这些,在我们用命令行编译java文件,报”包未找到的错误“时,我们可以将相关的jar文件放在%java_home%/jre/lib/ext目录下,就可以正确完成编译过程!但是如果把包放在%java_home%/lib下,然后通过 ”我的电脑-属性-高级-系统变量“ 配置给classpath这种方法是不能解决这个问题的!
但这样在以后运行应用程序时会产生一些莫名的错误,那时真是生不如死的感觉!
但是只要写一个批处理文件,就可以不必那么麻烦,每次都要设置classpath路径,一个批处理文件就搞定!
………………………………………………… compile.bat ………………………………………………………
set CLASSPATH=E:\soft\apache-tomcat-6.0.16\apache-tomcat-6.0.16\lib\servlet-api.jar;%CLASSPATH%
javac -d D:\testJsp\WEB-INF\classes %1
pause
…………………………………………………………………………………………………………………………………
OK 大功告成兄弟们!%1为传入的参数,只要将需要编译的java文件拖进来就可以编译成功并放到指定的目录中!其中E:\soft\apache-tomcat-6.0.16\apache-tomcat-6.0.16\lib\servlet-api.jar 是我本机serlet jar文件的目录, D:\testJsp\WEB-INF\classes 是我自己配置的一个tomcat服务器虚拟目录的地址!
TOMCAT中的类装载器:
bootstrap bootstrap类是java虚拟机内嵌的装载类和ExtClassLoder(%java_home%/jre/lib/ext)的总称!
System 系统类装载器,也就是AppClassLoder,负责加载classpath中的类,
commom 可以被每个web应用程序(可见)所使用,负责加载�talina_home%/common/classes
Catalina sharted �talina_home%/common/lib中的jar包加载类
webApp1 webapp2 Catalina负责加载�talina_home%/server/classes中的类文件和
�talina_home%/server/lib中的jar包加载类
sharted负责加载�talina_home%/share/classes中的类文件和
�talina_home%/share/lib中的jar包加载类
sun公司发布了一个标准类加载规范,但是各厂商觉得这个规范没什么实际作用,所以就没有按此标准来实现,还是按照类加载的代理模式来实现!先由父级类加载器加载,如果装载不到然后由子类装载器调用findclass()方法来查找装载类!