一、类加载器
(1)、三个类加载器
Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,BootStrap,ExtClassLoader,AppClassLoader。每个类加载器负责加载特定位置的类。
(2)、BootStrap
BootStrap嵌套在javaJVM内核中,是用c++语言写的二进制代码,随JVM的运行而运行,它不是java类。ExtClassLoader,AppClassLoader是java类,需要被BootStrap加载。
(3)、三个类加载器的管辖范围
BootStrap负责加载JRE/lib/rt.jar下的类文件。System类是由BootStrap加载的。
ExtClassLoader负责加载JRE/lib/ext/*.jar下的类文件。
AppClassLoader负责加载CLASSPATH指定的所有jar或目录下的类文件
(4)、继承结构
a)、获得类加载器的名称:
一般类.class.getClassLoader().getClass().getName() ,获得类加载器—>取得类加载器的字节码—>取得名称。 结果是AppClassLoader。
b)、代码:
<code>
ClassLoader loader = ClassLoaderTest.class.getClassLoader() ;
while(loader !=null ){
System.out.println(loader.getClass().getName()) ;
loader
System.out.println(loader.getClass().getName())
}</code>
可以得出AppClassLoader是ExtClassLoader的子类。
二、 类加载器的委托代理机制
1、类加载器结构图
2、自定义类加载器
a)、父加载器
i、系统默认的父加载器
自定义类加载器时需要指定父加载器,系统默认的是SystemClassLoader
ii、定义父加载器
自定义类加载器,必须继承抽象类ClassLoader。子类需要复写findClass(String name)方法。使用了模板方法模式。
iii、 ClassLoader中的方法:
loadClass(String name)
findClass()
defineClass()
b)、加载类
i可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
ii 当java虚拟机要加载一个类时,到底要派出那个类加载器去加载呢?
首先,当前线程的类加载器去加载线程中的第一个类如果类A中引用了类B,java虚拟机将使用加载类A的类加载器来加载类B。还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
iii、每个类加载器加载类时,又先委托给其上级类加载器
当所有高级类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛出ClassNotFoundException,不是再去找发起者类加载器的下级类加载器,因为没有获得下级类加载器的方法(获得上级类加载器的方法是getParents())。
c)、带加密功能的类加载器
Public static void main(String[] args){
String srcPath = args[0] ;
String destPath = args[1] ;
FileInputStream fis = new FileInputStream(srcPath) ;//源文件
String destFileName = srcPath.substring(srcPath.lastIndexOf(‘\\’)+1);
String destFilePath = destSrc + “\\”
FileOutputStream fos = new FileOutputStream(destPath) ;//目的目录
cypher(fis,fos);
fis.close() ;
fos.close();
}
private static void cypher(InputStream ips , OutputStream ops)throws Exception{
int
while((b = ips.read())!=-1){
ops.write(b^oxff);//加密
}
}
public
public String toString(){
}
}