ClassLoader类加载器
1、分为三种:
BootStrap ClassLoader(核心类加载器):最顶层的加载类,主要加载核心类库。%java_home%/jre/lib/rt.jar、resources.jar及class文件。由c语言编写,不能引用。
Extention ClassLoader(扩展类加载器):%java_home%/jre/lib/ext里的jar包和class文件,还可以加载-D java.ext.dirs选项指定的目录。没有父加载器,默认上级加载器为BootStrap ClassLoader。
App/System ClassLoader(应用程序类加载器):加载当前应用的classpath的所有类或 -Djava.class.path 下的类库。自定义的类如果没有指定父类加载器则默认的父加载器为AppClassLoader。
2、加载顺序:
BootStrap ClassLoader
Extention ClassLoader
AppClassLoader
3、双亲委托:
向上委托、向下查找。
先从自定义的类的附加器AppClassLoader在缓存里查找,若没有,则向上委托给ExtClassLoader,ExtClassLoader从缓存里查找,没有,则向上委托给BootStrapClassLoader,BootStapClassLoader从缓存里查找,若没有,则在BootStap默认的路径sun.mic.boot.class查找,若没有,则让下一个加载器ExtClassLoader在默认的路径java.ext.dirs查找,如果没有,则让下一级的加载器AppClassLoader在classPath属性下的java.class.path下查找。
4、自定义类加载器(继承 java.lang.ClassLoader 的自定义类加载器)
生成Test.class文件
自定义类加载文件DiskClassLoader
package com.syc.javatest;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class DiskClassLoader extends ClassLoader {
public Stringpath;
public DiskClassLoader(String path){
this.path = path;
}
protected ClassfindClass(String name)throws ClassNotFoundException{
String fileName = getFileName(name);
File file =new File(path,fileName);
try {
FileInputStream is =new FileInputStream(file);
ByteArrayOutputStream bos =new ByteArrayOutputStream();
int len;
try {
while((len=is.read())!=-1){
bos.write(len);
}
byte[] data = bos.toByteArray();
bos.close();
is.close();
return defineClass(name,data,0,data.length);
}catch (IOException e) {
e.printStackTrace();
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}
return super.findClass(name);
}
//获取要加载 的class文件名
private StringgetFileName(String name) {
// TODO Auto-generated method stub
int index = name.lastIndexOf('.');
if(index == -1){
return name+".class";
}else{
return name.substring(index)+".class";
}
}
}
测试自定义类加载器
package com.syc.javatest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class classLoaderTest {
public static void main(String[] args) {
//测试自定义的DiskClassLoader
DiskClassLoader dcl =new DiskClassLoader("D:\\javaTest\\src\\com\\syc\\javatest");
try {
Class c = dcl.loadClass("com.syc.javatest.Test");
if(c!=null){
try {
Object obj = c.newInstance();
Method method = c.getDeclaredMethod("say",null);
method.invoke(obj,null);
}catch (InvocationTargetException e) {
e.printStackTrace();
}catch (NoSuchMethodException e) {
e.printStackTrace();
}catch (InstantiationException e) {
e.printStackTrace();
}catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行结果: