实现自定义类加载器(自定义文件系统类加载器)
package cn.com.lodar;
import java.io.*;
public class FileSystemClassLoader extends ClassLoader{
//自定义文件系统类加载器
private String rootDir;
public FileSystemClassLoader(String rootDir) {
this.rootDir = rootDir;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> c = findLoadedClass(name);//查找这个类
//查找这个类是否被加载过,如果有,直接返回加载好的类,如果没有,加载新的类
if (c != null) {
return c;
}else {
ClassLoader parent = this.getParent();//获得父类的加载器
try {
c = parent.loadClass(name); //委派给父类加载
}catch(Exception e) {
// e.printStackTrace();
}
// c = parent.loadClass(name);
if (c != null) {
return c;
}else {
byte[] classData = getClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
}else {
c = defineClass(name,classData,0,classData.length);
}
}
}
return c;
}
private byte[] getClassData(String classname){
String path = rootDir+"/"+classname.replace('.','/')+".class";
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
is = new FileInputStream(path);
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int tmp;
while((tmp = is.read(bytes)) != -1) {
baos.write(bytes,0,tmp);
}
baos.flush();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
测试用例
package cn.com.lodar;
public class TestFileSystemClassLoader {
public static void main(String[] args) throws ClassNotFoundException {
FileSystemClassLoader loader = new FileSystemClassLoader("F:/myjava");
FileSystemClassLoader loader1 = new FileSystemClassLoader("F:/myjava");
Class<?> c = loader.loadClass("cn.com.test.HelloWord");
Class<?> c2 = loader.loadClass("cn.com.test.HelloWord");
Class<?> c3 = loader1.loadClass("cn.com.test.HelloWord");
Class<?> c4 = loader1.loadClass("java.lang.String");
Class<?> c5 = loader1.loadClass("cn.com.lodar.Demo02");
// System.out.println(c);
System.out.println(c.hashCode());//同一个类加载器加载同一个类,JVM才认为是同一个类
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());//不是同一个类加载器加载同一个类,JVM认为是不同的类
System.out.println(c4.hashCode());
System.out.println(c3.getClassLoader()); //自定义类加载器
System.out.println(c4.getClassLoader()); //引导类加载器
System.out.println(c5.getClassLoader()); //系统默认的类加载器
}
}