JVM默认加载器分为四种

BootstrapClassLoader(引导类加载器)

ExtensionClassLoader(扩展类加载器)

AppClassLoader(App加载器)

UserDefineClassLoader(自定义加载器)

双亲委派机制

图片

JVM三种加载器相互配合使用,按需加载,当我们需要使用该类的时候,就会生成class文件加载到内存当中生成class对象使用,加载的过程使用的就是双亲外派机制,如上图

双亲委派就是特定的加载器接收到了加载类的请求,然后会先将任务委托给父类来进行请求,父类接收到请求,如果它还有父类他就会继续向上请求,接着请求父类加载这个类,当父类无法加载这个类时,就会向下返回给子类,字类加载器才会进行加载。

双亲委派的好处

  1. 避免了重复加载使用
  2. 保证java库的安全,从外部接收到包的时候,不会将其随便解析,会先进行双亲委派进行判断,保证我们的java核心库不会被恶意篡改,类似出现用户自定义java.lang.Object类的情况

ClassLoader

  1. loadClass 加载指定的Java类
  2. findLoadedCLass 查找JVM已经加载过的类
  3. defineClass 定义一个Java类,将字节码解析成虚拟机识别的Class对象
  4. findClass 查找指定的Java类
  5. resolveClass 链接指定的Java类

URLClassLoader

URLClassLoader类继承CLassLoader类,可以加载本地磁盘和网络种的jar包类文件

package com.test;
public class Test {
    public Test(){
        System.out.println("Test success!!");
        try{
            Runtime.getRuntime().exec("cmd /c calc.exe");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用javac编译,在D盘生成class文件

1. 本地磁盘class文件调用

package com.Classloader;

import java.io.*;
import java.net.URL;
import java.net.URLClassLoader;

public class CLassLoaderTest{
    public static <Url> void main(String []args) throws Exception {
        File file = new File("d:/");
        URL url = file.toURI().toURL();

        URLClassLoader classloader = new URLClassLoader(new URL[]{url});
        Class clazz = classloader.loadClass("com.test.Test");
        clazz.newInstance();
    }
}

通过file获取到文件路径,利用URLClassLoader方式去获取D盘中的Test.class文件,使用loadclass获取包名,最后使用newInstance()函数调用对象 实例化。运行后会解析Teest.class文件

image-20231226215423239

2. 网络传输class文件调用

我们在Test.class文件下开启Tomcat服务。新建ClassLoaderDemo类网络加载Tomcat服务器中的Test.class

package com.Classloader;

import java.net.URL;
import java.net.URLClassLoader;

public class ClassLoaderDemo {
    public static void main(String[] args) throws Exception {
        URL url = new URL("http://localhost:8080/examples/");
        URLClassLoader classLoader = new URLClassLoader(new URL[]{url});
        Class clazz = classLoader.loadClass("com.test.Test");
        clazz.newInstance();
    }
}

这里使用URLClassLoader加载网络中的Tomcat服务器目录,成功解析获取到了目录下的Test.class文件

image-20231226220418062

ClassLoader总结

ClassLoader是JVM中一个非常重要的组成部分,ClassLoader可以为我们加载任意的java类,通过自定义ClassLoader更能够实现自定义类加载行为。