类加载器及委托机制

什么是类加载

在运行着的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);//异或运算    
    }
}
posted @ 2021-06-29 16:37  danaohu  阅读(80)  评论(0)    收藏  举报