ToB企服应用市场:ToB评测及商务社交产业平台
标题:
01java反序列化基础
[打印本页]
作者:
石小疯
时间:
2025-1-2 20:21
标题:
01java反序列化基础
java反射的相关操作
一些重要的方法
获取类的⽅法: forName
实例化类对象的⽅法: newInstance
获取函数的⽅法: getMethod
执⾏函数的⽅法: invoke
// eg.反射获取任意类的任意方法并执行
import java.lang.reflect.Method;
public class ReflectionExample {
public static void main(String[] args) {
try {
// 获取类名
Class<?> clazz = Class.forName("com.example.SomeClass");
// 获取方法名和参数类型
String methodName = "someMethod";
Class<?>[] parameterTypes = {String.class, int.class};
// 获取方法
Method method = clazz.getMethod(methodName, parameterTypes);
// 创建类的实例
Object obj = clazz.newInstance();
// 准备参数
Object[] arguments = {"example", 123};
// 执行方法
Object result = method.invoke(obj, arguments);
// 打印结果
System.out.println("Method returned: " + result);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
}
}
}
复制代码
forName
forName 不是获取“类”的唯⼀途径
obj.getClass() 如果上下⽂中存在某个类的实例 obj ,那么我们可以直接通过
obj.getClass() 来获取它的类
Test.class 如果你已经加载了某个类,只是想获取到它的 java.lang.Class 对象,那么就直接
拿它的 class 属性即可。这个⽅法其实不属于反射。
Class.forName 如果你知道某个类的名字,想获取到这个类,就可以使⽤ forName 来获取
forName的重载
forName(String name)和Class forName(String name,
boolean
initialize, ClassLoader loader)两个重载Class
ClassLoader loader就是⼀个“加载器”,一样平常是一个类的完备路径,如java.lang.Runtime
boolean
initialize决定是否进行“类初始化”,forName(String name)默认initialize=true
关于类初始化的补充:下面代码的执行顺序为static{}, 构造函数的 super(),{},构造函数,static{}即为类初始化
public class TrainPrint {
{
System.out.printf("Empty block initial %s\n", this.getClass());
}
static {
System.out.printf("Static initial %s\n", TrainPrint.class);
}
public TrainPrint() {
super();
System.out.printf("Initial %s\n", this.getClass());
}
}
复制代码
newInstance
class.newInstance() 的作用就是调用这个类的无参构造函数,于是乎不成功是由于:
你利用的类没有无参构造函数
你利用的类构造函数是私有的,例如java.lang.Runtime,可以采用类的其他静态方法获取实例
newInstance的补充getConstructor
Java和C++不同,C++的类必须有一个无参构造函数(显示定义或者编译器自动天生),而Java一但显示定义了任意构造函数,编译器就不会再自动天生无参构造函数,这就造成了一个问题,Java中的类大概没有无参构造函数也没有可获取实例的其他方法,此时就需要getConstructor获取有参构造函数
Class clazz = Class.forName("java.lang.ProcessBuilder");
clazz.getMethod("start").invoke(clazz.getConstructor(List.class).newInstance(
Arrays.asList("calc.exe")));
);
复制代码
关于类的私有方法
类的私有方法可以通过getDeclared 系列的反射调用,与普通的 getMethod 、 getConstructor 区别是:
getMethod 系列方法获取的是当前类中所有公共方法,包括从父类继续的方法
getDeclaredMethod 系列方法获取的是当前类中“声明”的方法,是实在写在这个类里的,包括私
有的方法,但从父类里继续来的就不包含了
Class clazz = Class.forName("java.lang.Runtime");
Constructor m = clazz.getDeclaredConstructor();
// setAccessible(true)修改作用域是必须得
m.setAccessible(true);
clazz.getMethod("exec", String.class).invoke(m.newInstance(), "calc.exe");
复制代码
反射的一些特性
无需import类
可以访问私有方法
不同语言的序列化对比
PHP序列化
[code]
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4