一,ClassLoader的四个实验
public class ClassLoaderTest extends TestCase {
//任务1:输出加载自己所编写类(具体为Temp类)的classloader和ArrayList的classloader
public void testGetClassLoader_Name(){
System.out.println(
Temp.class.getClassLoader().getClass().getName()
);
//下列输出结果为null,并不代表ArrayList没有类加载器,而是因为ArrayList的类加载器不是一个类,而是一段c++写的二进制代码
System.out.println(
ArrayList.class.getClassLoader()
);
}
//任务2:输出类加载器的parent(上级加载器,父级加载器)
public void testGetClassLoader_parent(){
ClassLoader loader=ClassLoaderTest.class.getClassLoader();
while(loader!=null){
String name=loader.getClass().getName();
System.out.println(name);
loader=loader.getParent();
}
}
//任务3:将自己编写的Temp类的class文件导出到jre/lib/ext目录下,再次观察Temp类的类加载器
public void testGetClassLoader_ext(){
//result:sun.misc.Launcher$ExtClassLoader
//注意:改变Temp中内容是再次运行,程序不会运行改变后的代码,因为改变后的代码编译的class文件在bin目录下不会被加载,
//真正加载的是ext目录没有重新编译的下的class文件.只有重启eclipse,删除ext目录下jar文件时,才会生效。
System.out.println(
Temp.class.getClassLoader().getClass().getName()
);
}
//任务4:编写自己的ClassLoader,指定Temp2类用自己编写的ClassLoader加载
public void testCustomClassLoader() throws Exception{
Class clazz=new MyClassLoader().loadClass("day2.Temp2");
Date date=(Date) clazz.newInstance();
System.out.println(date.getClass().getClassLoader());
System.out.println(date.toString());;
}
}
二 自定义ClassLoader类的代码
/**
* 思路:
* 重写其findClass方法
* 利用defineClass方法,把二进制文件转换为Class对象
* @author yajun
*/
public class MyClassLoader extends ClassLoader {
@SuppressWarnings("deprecation")
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte buff[]=new byte[1024];
byte[] clazzByte = null;
FileInputStream fis=null;
Class clazz=null;
int len=0;
System.out.println("进入MyClassLoader的findClass方法,获取参数name,值为:"+name);
try {
//1.将字节码文件读取到输出流
name=name.substring(name.lastIndexOf('.')+1);//取子串,获取类名
fis=new FileInputStream("lib\\"+name+".class");
ByteArrayOutputStream baos=new ByteArrayOutputStream();
while((len=fis.read(buff))!=-1){
baos.write(buff,0,len);
}
//2.将输出流中的字节码转换成class对象
clazzByte=baos.toByteArray();
clazz=defineClass(clazzByte, 0, clazzByte.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return clazz;
}
}