先讲一下Java类动态加载方式

Java类动态加载方式

Java类加载方式分为显式和隐式

  • 显式即我们通常使用Java反射或者ClassLoader来动态加载一个类对象
  • 隐式指的是类名.方法名()new类实例

显式加载

Class.forName()方式

// 默认初始化类
Class<?> clazz = Class.forName("com.example.MyClass");

// 控制初始化的重载方法
Class<?> clazz = Class.forName(
"com.example.MyClass",
false, // 是否初始化
Thread.currentThread().getContextClassLoader()
);

ClassLoader.loadClass()方式

// 使用系统类加载器
Class<?> clazz = ClassLoader.getSystemClassLoader()
.loadClass("com.example.MyClass");

// 使用当前类加载器
Class<?> clazz = getClass().getClassLoader()
.loadClass("com.example.MyClass");

Class.forName("类名")默认会初始化被加载类的静态属性和方法,如果不希望初始化类可以使用Class.forName("类名", 是否初始化类, 类加载器)

若用ClassLoader.loadClass, 该方式默认不会初始化类方法

隐式加载

ClassName.staticMethod()
new ClassName()

Class.forName("类名")默认会初始化被加载类的静态属性和方法,如果不希望初始化类可以使用Class.forName("类名", 是否初始化类, 类加载器),而ClassLoader.loadClass默认不会初始化类方法。

反射是什么

反射: Java在运行时动态获取类信息、操作类属性和方法的能力

如何获取一个对象

  1. 获取类的 Class 对象实例
Class clz = Class.forName("com.zhenai.api.Apple");
  1. 根据 CLass 对象实例获取 Constructor 对象
Constructor appleConstructor = clz.getConstructor();
  1. 使用 Constructor 对象的 newInstance 方法获取反射类对象
Object appleObj = appleConstructor.newInstance();

如何调用某一个方法

  1. 获取方法的 Method 对象
Method setPriceMethod = clz.getMethod("setPrice", int.class);
  1. 利用 invoke 方法调用方法
setPriceMethod.invoke(appleObj, 14);

特点:

  • 突破封装性:可访问私有成员(需setAccessible(true))
  • 动态性:运行时才确定操作对象(如Class.forName("java.lang.Runtime"方法))
  • 自省能力:可获取类结构(方法、字段、注解等)

反射使攻击者能绕过Java的访问控制,操作Runtime等敏感类。

术语 作用 漏洞利用中的角色
反射 运行时动态操作类 突破Java安全机制的基础能力
反射获取方法 提取类中的特定方法 获取敏感方法(如 getRuntime
反射调用 动态执行方法 触发命令执行(如 exec())