jvm-类加载机制

JVM类加载机制

启动类加载器、扩展类加载器、应用类加载器
类加载器 所属包 描述
启动类加载器 JDK安装目录下lib目录
扩展类加载器 JDK安装目录下lib/ext目录
应用类加载器 程序员自己写的代码
自定义类加载器
手写自定义类加载器
  • MyClassLoader类
public class MyClassLoader extends ClassLoader{

    private String byteCodePath;

    public MyClassLoader(String byteCodePath) {
        this.byteCodePath = byteCodePath;
    }

    public MyClassLoader(ClassLoader parent, String byteCodePath) {
        super(parent);
        this.byteCodePath = byteCodePath;
    }

    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        String fileName = byteCodePath + className + ".class";
        BufferedInputStream bufferedInputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        
        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream(fileName));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        try {
            int len;
            byte[] data = new byte[1024];
            while ((len = bufferedInputStream.read(data)) != -1){
                byteArrayOutputStream.write(data, 0, len);
            }
            byte[] bytes = byteArrayOutputStream.toByteArray();
            return defineClass(null, bytes, 0, bytes.length);
        }catch (Exception e) {
            try {
                bufferedInputStream.close();
                byteArrayOutputStream.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
        return null;
    }
}
  • 测试类
public class MyClassLoaderTest {
    public static void main(String[] args) {
        MyClassLoader myClassLoader = new MyClassLoader("C:\\tsing\\");
        try {
            Class<?> person = myClassLoader.loadClass("Person");
            System.out.println(person.getClassLoader()); //com.tsing.jvm.classloader.MyClassLoader@6d6f6e28
            System.out.println(person.getClassLoader().getParent()); //sun.misc.Launcher$AppClassLoader@18b4aac2
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
  • 重点
    • 1、需要继承ClassLoader
    • 2、重写findClass方法
    • 3、调用defineClass方法
双亲委派模型
  • 说明
    • 1、自定义类加载器先不加载,它会去询问应用程序类加载器是否可以加载。
    • 2、应用程序类加载器也不会加载,它会去询问扩展类加载器是否可以加载。
    • 3、扩展类加载器也不会加载,它会去询问启动类加载器
    • 4、如果启动类加载器可以加载,就直接加载,不能加载推给扩展类加载器
    • 5、如果扩展类加载器可以加载,就直接加载,不能加载推给应用类加载器
    • 6、如果应用类加载器可以加载,就直接加载,不能加载推给自定义类加载器
    • 7、如果自定义类加载器可以加载,就直接加载,不能加载就会报classNotFound异常。
posted @ 2020-12-19 11:17  蜗牛|ICU  阅读(78)  评论(0编辑  收藏  举报