类加载器:装载方式:当编译器第一次检查到一个类名时,会把其.class文件或在classpath下的其他文件从硬盘加载到内存,再处理,转化为字节码。
用类装载的方式读取资源文件:2大问题
1通过类装载器读取文件时直接读到内存,文件不能太大!!
2 由于只装载一次,不能读到更新后的文件数据,只能用普通流去读取,通过类转载器获得资源的路径先
String path=UserDAO.class.getClassLoader().getResource (“cs.properties”).getPath();
FileInputStream fis=new FileInputStream(path);
jdk有jvm加载class文件和运行java对象,要保证该jdk版本和编译class文件的jdk要一致!!!
jvm有多个类加载器,每个加载器负责不同位置的.class文件,类加载器也是类
1BootStrap是内置在JVM内核里,由c++编写,可以加载其他类加载器类
class ClassLoaderTest{
main(){
1//自定义类getClassLoader()返回类加载器类的对象,也有自己的Class对象
ClassLoaderTest.class.getClassLoader().getClass().getName();
打印出类加载器的类名是AppClassLoader
2系统类的类加载器
System.class.getClassLoader().getClass().getName();
会报空指针异常,因为系统类的类加载器是BootStrap,BootStrap不是java类,所以不能获取其字节码
3ClassLoader loader= ClassLoaderTest.class.getClassLoader();
while(loader!=null){
//打印该类加载器的名字
print(loader.getClass().getName());
//获得其父 类加载器ClassLoader
loader=loader.getParent();
}
可以看出AppClassLoader的父 类加载器是ExtClassLoader
ExtClassLoader父 类加载器是BootStrap
}}
类加载器树
BootStrap 只加载JER/lib/rt.jar java系统类
ExtClassLoader加载JER/lib/ext/*.jar java扩展jar包
AppClassLoader 专门加载classpath所指定的目录下的.class或jar包
只能是jar包!!.class可以吗?
更改jar文件的类加载器:
只需要更改jar文件的目录
就是把jar文件复制到ext目录下
我们可以将自己的的java文件打成jar包输出到加载JER/lib/ext/从而让ExtClassLoader加载器加载
操作:点一个类或包,右击 -export-java-jar file-选择文件- ClassLoaderTest(自定义),但要小心,如果内存中已经有一个类的字节码,你再去运行修改后的类,只会运行之前的字节码!
或者有两个相同.class文件在不同目录,一个在ext下已经达成了jar包,另一个.class文件在classpath下,classpath下该.class文件不能得到执行,会直接加载ext下的
ClassLoaderTest.class.getClassLoader().getClass().getName();
打印出类加载器的类名是ExtClassLoader
当三个位置,有相同的jar文件时,首先由父加载器优先加载!
|