安全 安全开发 第34天:安全开发-JavaEE应用&反射机制&攻击链&类对象&成员变量方法&构造方法 Yatming的博客 2025-09-12 2025-08-04
1. 类加载与 Class 对象 当 Java 程序运行时,每个类都会被 JVM 加载到内存中,并生成一个对应的Class
对象(类似于类的 “元数据模板”)。这个Class
对象包含了该类的所有信息:字段、方法、构造器等。类比 :就像建筑图纸(Class
对象)包含了建筑物(类)的所有设计细节,程序可以通过图纸了解建筑物的结构。
2. 获取 Class 对象的三种方式 程序可以通过以下方式获取Class
对象:
类名.class :Class<?> clazz = Person.class;
对象.getClass () :Class<?> clazz = personInstance.getClass();
全类名反射 :Class<?> clazz = Class.forName("com.example.Person");
类比 :就像通过建筑物的名字、实际建筑或地址来获取对应的图纸。
3. 通过 Class 对象访问类成员 一旦获得Class
对象,就可以获取类的各种成员(字段、方法、构造器)的 “反射对象”:
获取字段 :Field field = clazz.getField("name");
获取方法 :Method method = clazz.getMethod("sayHello", String.class);
获取构造器 :Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
类比 :从图纸中找到房间(字段)、电梯(方法)或入口(构造器)的位置。
4. 动态创建对象与调用方法 反射允许在运行时动态创建对象、调用方法或修改字段值:
创建对象 :Person person = (Person) constructor.newInstance("Alice", 30);
调用方法 :method.invoke(person, "World");
修改字段 :field.set(person, "Bob");
类比 :根据图纸现场建造建筑物(创建对象),操作电梯(调用方法),或更改房间用途(修改字段)。
5. 反射的应用场景
框架开发 :Spring、Hibernate 等框架通过反射实现依赖注入、ORM 映射。
JSON 序列化 / 反序列化 :Gson、Jackson 通过反射解析对象字段。
插件系统 :动态加载外部类或模块。
调试工具 :查看对象的内部状态。
6.反射的优缺点
优点 :灵活、可扩展,适合框架和工具开发。
缺点 :性能开销大(比直接调用慢),破坏封装性(可访问私有成员),可能导致安全风险。
什么是反射,为什么要用到反射 1 参考:https://xz.aliyun.com/t/9117
演示 Java-反射-Class对象类获取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1、根据类名: 类名.class Class userClass = User.class; 2、根据对象: 对象.getClass() User user = new User(); Class aClass = user.getClass(); 3、根据全限定类名: Class.forName("全路径类名") Class aClass1 = Class.forName("com.example.reflectdemo.User"); 4、通过类加载器获得Class对象: ClassLoader.getSystemClassLoader().loadClass("全路径类名"); ClassLoader clsload=ClassLoader.getSystemClassLoader(); Class aClass2 = clsload.loadClass("com.example.reflectdemo.User");
新建项目,新建一个User的类
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package com.example.reflectdemo;public class User { public String name="xiaodi" ; public int age = 31 ; private String gender="man" ; protected String job="sec" ; public User () { } public User (String name) { System.out.println("我的名字" +name); } private User (String name,int age) { System.out.println(name); System.out.println(age); } public void userinfo (String name,int age,String gender,String job) { this .job=job; this .age=age; this .name = name; this .gender=gender; } protected void users (String name,String gender) { this .name = name; this .gender=gender; System.out.println("users成员方法:" +name); System.out.println("users成员方法:" +gender); } }
GetClass.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.example.reflectdemo; public class GetClass { public static void main (String[] args) throws ClassNotFoundException { Class aClass = Class.forName("com.example.reflectdemo.User" ); System.out.println(aClass); Class userClass = User.class; System.out.println(userClass); User user= new User (); Class aClass1 = user.getClass(); System.out.println(aClass1); ClassLoader clsload=ClassLoader.getSystemClassLoader(); Class aClass2 = clsload.loadClass("com.example.reflectdemo.User" ); System.out.println(aClass2); } }
Java-反射-Field成员变量类获取
GetFiled
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package com.example.reflectdemo;import java.lang.reflect.Field;public class GetFiled { public static void main (String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { Class aClass = Class.forName("com.example.reflectdemo.User" ); Field[] fields = aClass.getFields(); for (Field fd:fields){ System.out.println(fd); } User u = new User (); Field field=aClass.getField("name" ); Object a=field.get(u); System.out.println(a); } }
获取公共成员变量
获取所有成员变量
获取单个的公共成员变量 && 获取单个成员变量
赋值修改
Java-反射-Method 成员方法类获取
GetMethod
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.example.reflectdemo;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class GetMethod { public static void main (String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class aClass = Class.forName("com.example.reflectdemo.User" ); Method[] methods = aClass.getMethods(); for (Method me:methods){ System.out.println(me); } } }
获取包括继承的公共成员方法
获取不包括继承的所有成员方法
获取单个的成员方法
对成员方法进行执行
Java-反射-不安全命令执行&反序列化链 GetRunExec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.example.reflectdemo;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class GetRunExec { public static void main (String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class aClass = Class.forName("java.lang.Runtime" ); Method exec = aClass.getMethod("exec" , String.class); Method getRuntimeMethod = aClass.getMethod("getRuntime" ); Object runtime = getRuntimeMethod.invoke(aClass); exec.invoke(runtime, "calc.exe" ); } }
原生调用 这里有点像,调用java自带的执行系统命令的函数。
第三方调用
目录结构:
java中各种类型的访问修饰符 公共方法(Public Method) 类比 :公共方法就像是一个人的 “公开技能”,任何人都可以使用或调用。特点 :
可以被类外部的代码访问(如其他类、对象)。
用于暴露类的功能,是类与外部交互的接口。
私有方法(Private Method) 类比 :私有方法就像是一个人的 “内部思考过程”,只能在自己的大脑(类内部)使用。特点 :
只能在定义它的类内部被调用。
用于封装类的内部实现细节,不对外公开。
保护方法(Protected Method) 类比 :保护方法就像是一个家族的 “祖传手艺”,只有家族成员(子类)可以继承和使用。特点 :
可以被同一个包内的类访问,也可以被不同包的子类访问。
用于在继承体系中共享功能,但限制外部访问。
访问修饰符
类内部
同一个包
不同包子类
其他类
public
✅
✅
✅
✅
protected
✅
✅
✅
❌
private
✅
❌
❌
❌
一句话总结
类 :定义事物的 “模板”。
公共方法 :对外提供的 “公开服务”。
私有方法 :内部使用的 “工具函数”。
保护方法 :家族内部共享的 “祖传秘方”。