一、类加载器关系
自定义类加载器
创建一个类继承ClassLoader类,同时重写findClass方法,用于判断当前类的class文件是否已被加载
二、基于本地class文件的自定义类加载器
本地class文件路径
自定义类加载器:
//创建自定义加载器类继承ClassLoader类 public class MyClassLoader extends ClassLoader{ // 包路径 private String Path; // 构造方法,用于初始化Path属性 public MyClassLoader(String path) { this.Path = path; } // 重写findClass方法,参数name表示要加载类的全类名(包名.类名) @Override protected Class<?> findClass(String name) throws ClassNotFoundException { System.out.println("findclass方法执行"); // <mark>本文来源gaodaimacom搞#代%码@网-</mark> 检查该类的class文件是否已被加载,如果已加载则返回class文件(字节码文件)对象,如果没有加载返回null Class<?> loadedClass = findLoadedClass(name); // 如果已加载直接返回该类的class文件(字节码文件)对象 if (loadedClass != null){ return loadedClass; } // 字节数组,用于存储class文件的字节流 byte[] bytes = null; try { // 获取class文件的字节流 bytes = getBytes(name); } catch (Exception e) { e.printStackTrace(); } if (bytes != null){ // 如果字节数组不为空,则将class文件加载到JVM中 System.out.println(bytes.length); // 将class文件加载到JVM中,返回class文件对象 Class<?> aClass = this.defineClass(name, bytes, 0, bytes.length); return aClass; }else { throw new ClassNotFoundException(); } } // 获取class文件的字节流 private byte[] getBytes(String name) throws Exception{ // 拼接class文件路径 replace(".",File.separator) 表示将全类名中的"."替换为当前系统的分隔符,File.separator返回当前系统的分隔符 String FileUrl = Path + name.replace(".", File.separator) + ".class"; byte[] bytes; // 相当于一个缓存区,动态扩容,也就是随着写入字节的增加自动扩容 ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(); File file = new File(FileUrl); // 创建输入流 InputStream inputStream = new FileInputStream(file); int content; // 循环将输入流中的所有数据写入到缓存区中 while ((content = inputStream.read()) != -1){ arrayOutputStream.write(content); arrayOutputStream.flush(); } bytes = arrayOutputStream.toByteArray(); return bytes; } }
测试类