ClassLoader类加载器
1、ClassLoader类加载器简介
在Java语言里面提供有一个系统的环境变量:CLASSPATH,这个环境属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指定路径中类的加载,也就是说找到了类的加载器就意味着找到了类的来源
系统类加载器
如果说现在要想获得类的加载器,那么一定要通过ClassLoader来获取,而要想获取ClassLoader_类的对象,则必须利用Class类(反射的根源)实现,方法:
- public ClassLoader getClassLoader()
当获取了ClassLoader之后还可以继续获取其父类的ClassLoader对象
- public final ClassLoader getParent()
类加载器
public class JavaDemo {
public static void main(String[] args) throws Exception {
Class<Person> aClass = Person.class;
System.out.println(aClass.getClassLoader());
System.out.println(aClass.getClassLoader().getParent());
System.out.println(aClass.getClassLoader().getParent().getParent());
}
}
//jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
//jdk.internal.loader.ClassLoaders$PlatformClassLoader@7c30a502
//null
当你获得了类加载器之后就可以利用类加载器来实现类的反射加载处理。
2、自定义ClassLoader处理类
自定义类加载器的加载顺序是在所有系统类加载的最后加载的
系统类中的类加载器都是根据CLASSPATH路径进行类加载的,而如果有了自定义加载器,就可以由开发者任意指派
1、随意编写一个程序类,并将此类保存到磁盘上
public class Message {
public void send(){
System.out.println("发送消息");
}
}
2、将此类拷贝到磁盘上进行编译处理,并且不打包:javac Message.java
此时并没有进行打包处理,所以这个类无法通过CLASSPATH正常加载
3、自定义一个类加载器,并且继承自ClassLoader类。在 ClassLoader类里面为用户提供有一个字节转换为类结构的方法
- protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError
public class TClassLoader extends ClassLoader{
private static final String MESSAGE_CLASS_PATH = "E:" + File.separator + "Message.class";
/**
* 进行指定类的加载
* @param className 类的完整名称“bao.类”
* @return 返回一个指定类的Class对象
* @throws Exception 如果类文件不存在则无法加载
*/
public Class<?> loadDate(String className) throws Exception{
byte [] data = this.loadClassData(); //读取二进制文件
if (data != null) { //读取到了
return super.defineClass(className , data , 0 , data.length);
}
return null;
}
/**
* 通过文件进行类的加载
*/
private byte [] loadClassData() throws Exception{
InputStream input = null;
//将数据加载到内存之中
ByteArrayOutputStream bos = null;
byte data [] = null;
try {
input = new FileInputStream(new File(MESSAGE_CLASS_PATH));
input.transferTo(bos); //读取数据
data = bos.toByteArray(); //将所有读取到的字节数据取出
} catch (Exception e){
e.printStackTrace();
} finally {
if (input != null) {
input.close();
}
if (bos != null) {
bos.close();
}
}
return data;
}
}
4、编写测试类经实现加载控制
public class JavaDemo {
public static void main(String[] args) throws Exception {
TClassLoader classLoader = new TClassLoader();
Class<?> aClass = classLoader.loadDate("com.xialuote.domain.Message");
Object obj = aClass.getDeclaredConstructor().newInstance();
Method method = aClass.getDeclaredMethod("send");
method.invoke(obj);
}
}
如果在以后结合到网络程序开发的话,就可以通过一个远程的服务器来确定类的功能。
如果自定义的加载类的名字与系统类名字一致,则不会被加载
下一篇:反射与代理设计模式