类加载器及委托机制
什么是类加载
在运行着的Java程序中,一切都是对象,
凡是对象都有对应的类,字节码对象也有所对应的Class类,void也有所属的类,通过反射可以验证
Class<void> voidClass = void.class;
类(.class文件)需要被加载到程序中,成为二进制字节码对象,才能被程序调用。
加载类的工具叫做类加载器,既然一切都是对象,类加载器也是被加载出来的。
而最上级类加载器就只能用c++的方式来实现啦;
自带三个类加载器
BootStrap
c++实现,最顶级类加载器
加载 JRE/lib/rt.jar中的类 (JAVA_HOME\jre\lib\rt.jar)
ExtClassLoader
加载 JRE/lib/rt.jar中的类 (JAVA_HOME\jre\lib\ext\*.jar)
AppClassLoader
classPath目录下的所有jar或目录
委托加载机制
自定义一个ClassLoader,需要继承ClassLoader接口,在构造方法中指定Parent
所有 类加载器是一个树形结构。
当Java虚拟机要加载一个类时,由当前线程指定的类加载器X去加载
thread.getContextClassLoader();
这个类加载器X不会直接加载类,会委托它的爸爸去加载,它的爸爸已经在构造方法中设定了。依此类推,直到顶级parent去加载rt.jar 如果没找到,就通知儿子去加载,依次类推,如果类加载器X仍然没有找到,则抛出ClassNotFoundException异常。
自定义类加载器
关键字:自定义类目录、类加密、加载解密
自定义类加载器的代码
package classLoader;
//必须继承ClassLoader
public class MyClassLoader extends ClassLoader {
//重写findClass方法
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] bytes = loadClassData(name);
return defineClass(name, bytes, 0, bytes.length);
}
private byte[] loadClassData(String name) {
//这里是你加载.class 文件到二进制数组的代码
return null;
}
}
编写对class文件进行加密的工具类
一个简单的加密解密工具,将二进制中的 0变成1、1变成0(看看就行,无实际意义)
public static void cyClazz(InputStream inputStream, OutputStream outputStream) throws IOException {
int b = -1;
while ((b=inputStream.read()) != -1)
{
outputStream.write(b^0xff);//异或运算
}
}
浙公网安备 33010602011771号