一、什么是类加载器?
加载类的工具。
二、类加载器有什么用?
官方:Java类加载器是Java运行时环境的一部分,负责动态加载Java类到Java虚拟机的内存空间中去。
自我理解:当程序需要某各类时,那么需要通过类加载器把类的二进制加载到内存中去。类加载器也是java类。
三、类加载器的工作原理:
①委托:委托机制是指将加载一个类的请求交给父类加载器,如果这个父类加载器不能够找到或者加载这个类,那么再加载它。可见性的原理是子类的加载器可以看见所有的父类加载器加载的类,而父类加载器看不到子类加载器加载的类。
②可见性:子类的加载器可以看见所有的父类加载器加载的类,而父类加载器看不到子类加载器加载的类。
③单一性:仅加载一个类一次,这是由委托机制确保子类加载器不会再次加载父类加载器加载过的类。
四、类加载器的三种类型:
<1>应用类加载器App:加载自己写的类或者jar包下面的类
<2>扩展类加载器Ext:加载jdk/jre/lib/ext/下面的所有jar包
<3>根类加载器null:加载jdk/jre/lib/jar(所有类加载器的父加载器)
五、代码实现
通过类加载器获取对象
@Test
public void testB(){ //2.通过类加载器获取对象
//2.1获取类对象
try {
Class clazz=Class.forName("com.sun.entity.Person");
//2.2获取类加载器
ClassLoader classLoader=clazz.getClassLoader();
ClassLoader classLoaderParent=classLoader.getParent();
ClassLoader classLoaderGrandParent=classLoaderParent.getParent();
//2.3查询类加载器的类型
System.out.println("自己:"+classLoader);
System.out.println("自己的父亲:"+classLoaderParent);
System.out.println("自己的爷爷:"+classLoaderGrandParent);
/*Person person=(Person) clazz.newInstance();
person.setPname("嚎猪");
System.out.println("类:"+person.getPname());
*/
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
自定义的类加载器
package com.sun.diy;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 自定义的类加载器
* @author Administrator
*
*/
public class ClassLoaderDIY extends ClassLoader{
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
System.out.println("自定义类加载器");
System.out.println("name:"+name);
//所有的.替换成\
name=name.replaceAll("\\.", "/");
System.out.println("name替换后:"+name);
//根据name找到桌面上想对应的person.class文件
int end=name.lastIndexOf("/");
name=name.substring(end);
System.out.println("截取后:"+name);
String desktopPath="D:\\桌面文件\\桌面\\"+name+".class";
System.out.println(desktopPath);
try {
FileInputStream fis=new FileInputStream(desktopPath);
try {
System.out.println(fis.available());
int len=0;
byte[] b=new byte[fis.available()];
len=fis.read(b);
return defineClass(null, b, 0, len);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
使用自己的类加载器
@Test
public void testC(){//使用自己的类加载器,加载对象
try {
Class clazz=Class.forName("com.sun.entity.Person",true,new ClassLoaderDIY());
System.out.println(clazz.newInstance());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}