Java类加载机制
Java程序在运行前需要先编译成class文件,Java类初始化的时候会调用java.lang.ClassLoader加载类字节码,ClassLoader会调用JVM的native方法(defineClass0/1/2)来定义一个java.lang.Class实例。
class文件
Java字节码类文件(.class)是Java编译器编译Java源文件(.java)产生的“目标文件”。它是一种8位字节的二进制流文件。
Java类加载机制
主要作用:Java类文件的加载进内存
Bootstrap ClassLoader(引导类加载器)
Extension ClassLoader(扩展类加载器)
App ClassLoader(系统类加载器)—默认的类加载器
ClassLoader.getSystemClassLoader()返回的系统类加载器也是AppClassLoader,见示例。
1 |
|
通过引导类加载器加载(该类加载器实现于JVM层,采用C++编写),获取一个类的类加载器时候会返回一个
null值,如loader3
java.io.File类同理间loader4
双亲委派
一个java类加载进JVM内存的过程
- 每个类加载器对他加载过的类都有缓存
- 向上委托查找,向下委托加载
JDK的类加载对象
1 | ClassLoader -> SecureClassLoader -> URLClassLoader -> ExtClassLoader,AppClassLoader |
ClassLoader类
抽象类,主要功能:通过指定的类名称,找到或生成对应的字节码,返回java.lang.Class类的实例。
ClassLoader类有如下和加载类相关的方法:
| 方法 | 说明 |
|---|---|
getParent() |
返回该类加载器的父类加载器 |
loadClass(String name) |
加载指定的Java类 |
findClass(String name) |
查找指定的Java类 |
findLoadedClass(String name) |
查找JVM已经加载过的类 |
defineClass(String name,byte[] b,int off,int len) |
字节数组b转成Java类 |
resolveClass |
链接指定的Java类 |
ClassLoader作用
根据文件地址获取输入流
1 | ClassLoader loader = this.getClass().getClassLoader(); |
Java类动态加载机制
显式:通常使用Java反射或者ClassLoader来动态加载一个类对象。
隐式:类名.方法名()或new类实例
常用的类动态加载方式:
1 | //默认会初始化被加载类的静态属性和方法 |
自定义ClassLoader
- 继承一个系统类加载器。
- 覆盖父类的findClass方法。
- 在方法中,调用defineClass方法在JVM内存中定义一个类。
自己的类加载器来实现加载自定义的字节码
1 | package com.drop.test; |
类加载隔离

1 | package com.drop.test; |
动态加载字节码的几种方法
URLClassLoader
java.lang.ClassLoader是所有的类加载器的父类,java.lang.ClassLoader有非常多的子类加载器,比如我们用于加载jar包的java.net.URLClassLoader其本身通过继承java.lang.ClassLoader类,重写了findClass方法从而实现了加载目录class文件甚至是远程资源文件。
1 | //Hello.java |

构造恶意类
static方法
在没有创建对象的情况下来进行调用(方法/变量)
1 | import java.io.IOException; |
远程调用
1 | public class TestURLClassLoader { |







