Java反射案例如何基础实操

wen java案例 24

Java反射基础实操案例

准备工作

创建一个待反射操作的类:

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);
    }
}

注意事项和常见问题

  1. 性能问题:反射操作比普通调用慢,循环中尽量避免
  2. 安全检查:访问private成员需要setAccessible(true)
  3. 异常处理:反射会抛出多种异常,如ClassNotFoundExceptionNoSuchMethodException
  4. 类型转换:反射返回Object类型,需要正确转换
  5. Java模块系统:Java 9+模块化后,需要谨慎处理模块访问权限

通过这些案例,你可以掌握Java反射的基础实操技能,建议从最简单的获取Class对象开始,逐步练习到操作字段和方法。

抱歉,评论功能暂时关闭!