Java反射基础实操案例
准备工作
创建一个待反射操作的类:

package com.example;
public class User {
private String name;
private int age;
public User() {}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 私有方法
private void privateMethod() {
System.out.println("私有方法被调用");
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
基础反射操作案例
获取Class对象的三种方式
public class ReflectionDemo {
public static void main(String[] args) throws Exception {
// 方式1:使用Class.forName()
Class<?> class1 = Class.forName("com.example.User");
// 方式2:使用.class语法
Class<?> class2 = User.class;
// 方式3:使用getClass()方法
User user = new User();
Class<?> class3 = user.getClass();
System.out.println("三种方式获取的Class相同吗?" +
(class1 == class2 && class2 == class3)); // true
}
}
获取类的完整信息
public class ClassInfoDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.example.User");
// 获取类名
System.out.println("类名:" + clazz.getName());
System.out.println("简单类名:" + clazz.getSimpleName());
// 获取包名
System.out.println("包名:" + clazz.getPackage().getName());
// 获取所有public方法(包括父类)
Method[] methods = clazz.getMethods();
System.out.println("\n所有public方法:");
for (Method method : methods) {
System.out.println(" " + method.getName());
}
// 获取所有声明的方法(不包括父类)
Method[] declaredMethods = clazz.getDeclaredMethods();
System.out.println("\n所有声明的方法(包括私有):");
for (Method method : declaredMethods) {
System.out.println(" " + method.getName());
}
// 获取所有字段
Field[] fields = clazz.getDeclaredFields();
System.out.println("\n所有字段:");
for (Field field : fields) {
System.out.println(" " + field.getName() + " - " + field.getType());
}
// 获取所有构造方法
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
System.out.println("\n所有构造方法:");
for (Constructor<?> constructor : constructors) {
System.out.println(" " + constructor);
}
}
}
创建对象实例
public class CreateInstanceDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.example.User");
// 方式1:使用newInstance()(已过时,但兼容)
User user1 = (User) clazz.newInstance();
System.out.println("方式1:" + user1);
// 方式2:使用Constructor
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class);
User user2 = (User) constructor.newInstance("张三", 25);
System.out.println("方式2:" + user2);
// 方式3:使用默认构造器
Constructor<?> defaultConstructor = clazz.getDeclaredConstructor();
User user3 = (User) defaultConstructor.newInstance();
System.out.println("方式3:" + user3);
}
}
操作字段(属性)
public class FieldOperationDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.example.User");
Object user = clazz.getDeclaredConstructor().newInstance();
// 获取并修改public字段
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true); // 访问私有字段
// 设置值
nameField.set(user, "李四");
// 获取值
String name = (String) nameField.get(user);
System.out.println("name = " + name);
// 修改private字段
Field ageField = clazz.getDeclaredField("age");
ageField.setAccessible(true);
ageField.set(user, 30);
int age = (int) ageField.get(user);
System.out.println("age = " + age);
System.out.println("最终user:" + user);
}
}
调用方法
public class MethodOperationDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.example.User");
Object user = clazz.getDeclaredConstructor().newInstance();
// 调用setName方法
Method setNameMethod = clazz.getDeclaredMethod("setName", String.class);
setNameMethod.invoke(user, "王五");
// 调用getName方法
Method getNameMethod = clazz.getDeclaredMethod("getName");
String name = (String) getNameMethod.invoke(user);
System.out.println("getName() 返回:" + name);
// 调用私有方法
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
privateMethod.setAccessible(true); // 访问私有方法
privateMethod.invoke(user);
// 调用带返回值的方法
Method toStringMethod = clazz.getDeclaredMethod("toString");
String result = (String) toStringMethod.invoke(user);
System.out.println("toString() 返回:" + result);
}
}
综合案例:通用对象操作工具类
public class ReflectionUtils {
// 动态创建对象
public static <T> T createInstance(Class<T> clazz, Object... args) throws Exception {
if (args == null || args.length == 0) {
return clazz.getDeclaredConstructor().newInstance();
}
Class<?>[] paramTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
paramTypes[i] = args[i].getClass();
}
Constructor<T> constructor = clazz.getDeclaredConstructor(paramTypes);
return constructor.newInstance(args);
}
// 调用对象方法
public static Object invokeMethod(Object obj, String methodName, Object... args) throws Exception {
Class<?> clazz = obj.getClass();
Class<?>[] paramTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
paramTypes[i] = args[i].getClass();
}
Method method = clazz.getDeclaredMethod(methodName, paramTypes);
method.setAccessible(true);
return method.invoke(obj, args);
}
// 设置字段值
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
// 获取字段值
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
}
// 打印对象所有字段值
public static void printObjectFields(Object obj) throws Exception {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
System.out.println("=== " + clazz.getSimpleName() + " 字段信息 ===");
for (Field field : fields) {
field.setAccessible(true);
System.out.println(field.getName() + " = " + field.get(obj));
}
}
}
使用工具类
public class ReflectionTest {
public static void main(String[] args) throws Exception {
// 1. 创建对象
User user = ReflectionUtils.createInstance(User.class, "测试用户", 20);
System.out.println("创建对象:" + user);
// 2. 调用方法
ReflectionUtils.invokeMethod(user, "setName", "新名字");
String name = (String) ReflectionUtils.invokeMethod(user, "getName");
System.out.println("调用方法后name:" + name);
// 3. 设置字段
ReflectionUtils.setFieldValue(user, "age", 25);
System.out.println("设置字段后age:" + ReflectionUtils.getFieldValue(user, "age"));
// 4. 打印所有字段
ReflectionUtils.printObjectFields(user);
}
}
注意事项和常见问题
- 性能问题:反射操作比普通调用慢,循环中尽量避免
- 安全检查:访问private成员需要
setAccessible(true) - 异常处理:反射会抛出多种异常,如
ClassNotFoundException、NoSuchMethodException等 - 类型转换:反射返回Object类型,需要正确转换
- Java模块系统:Java 9+模块化后,需要谨慎处理模块访问权限
通过这些案例,你可以掌握Java反射的基础实操技能,建议从最简单的获取Class对象开始,逐步练习到操作字段和方法。