Java反射获取属性案例如何实现

wen java案例 21

Java反射获取属性的几种实现方式

获取所有公共属性(包括继承的)

import java.lang.reflect.Field;
public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // 获取Class对象
            Class<?> clazz = Class.forName("com.example.User");
            // 获取所有公共属性(包括继承的)
            Field[] fields = clazz.getFields();
            System.out.println("所有公共属性:");
            for (Field field : fields) {
                System.out.println("属性名: " + field.getName() + 
                                 ", 类型: " + field.getType().getName());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

获取所有声明的属性(不包括继承的)

public class ReflectionExample2 {
    public static void main(String[] args) {
        Class<?> clazz = User.class;
        // 获取所有声明的属性(包括private,但不包括继承的)
        Field[] declaredFields = clazz.getDeclaredFields();
        System.out.println("所有声明的属性:");
        for (Field field : declaredFields) {
            System.out.println("属性名: " + field.getName() + 
                             ", 修饰符: " + Modifier.toString(field.getModifiers()) +
                             ", 类型: " + field.getType().getSimpleName());
        }
    }
}
// 示例类
class User {
    public String name;
    private int age;
    protected String email;
    String address;  // 默认访问权限
    public static final String TYPE = "USER";
}

获取单个属性并操作

public class ReflectionExample3 {
    public static void main(String[] args) throws Exception {
        // 创建对象实例
        User user = new User("张三", 25);
        // 获取Class对象
        Class<?> clazz = user.getClass();
        // 获取指定属性
        Field nameField = clazz.getField("name");  // 获取公共属性
        Field ageField = clazz.getDeclaredField("age");  // 获取声明属性(包括私有)
        // 访问私有属性时需要设置可访问
        ageField.setAccessible(true);
        // 获取属性值
        String name = (String) nameField.get(user);
        int age = (int) ageField.get(user);
        System.out.println("修改前 - name: " + name + ", age: " + age);
        // 修改属性值
        nameField.set(user, "李四");
        ageField.set(user, 30);
        System.out.println("修改后 - name: " + user.getName() + ", age: " + user.getAge());
    }
}
class User {
    public String name;
    private int age;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() { return name; }
    public int getAge() { return age; }
}

获取属性的完整信息

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class ReflectionExample4 {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = User.class;
        // 获取所有属性
        Field[] fields = clazz.getDeclaredFields();
        System.out.println("属性详细信息:");
        for (Field field : fields) {
            System.out.println("\n属性名: " + field.getName());
            System.out.println("类型: " + field.getType().getName());
            System.out.println("修饰符: " + Modifier.toString(field.getModifiers()));
            // 获取注解
            Annotation[] annotations = field.getAnnotations();
            if (annotations.length > 0) {
                System.out.println("注解: ");
                for (Annotation annotation : annotations) {
                    System.out.println("  - " + annotation.annotationType().getName());
                }
            }
            // 获取泛型类型(如果有)
            Type genericType = field.getGenericType();
            if (genericType instanceof ParameterizedType) {
                ParameterizedType paramType = (ParameterizedType) genericType;
                Type[] actualTypes = paramType.getActualTypeArguments();
                System.out.println("泛型参数: ");
                for (Type type : actualTypes) {
                    System.out.println("  - " + type.getTypeName());
                }
            }
        }
    }
}
// 带注解和泛型的示例类
class Person {
    @Deprecated
    public String name;
    public List<String> tags;
    private Map<String, Integer> scores;
    // ...
}

实用工具方法

public class ReflectionUtils {
    /**
     * 获取对象的所有字段名和值
     */
    public static Map<String, Object> getAllFields(Object obj) throws Exception {
        Map<String, Object> result = new HashMap<>();
        Class<?> clazz = obj.getClass();
        // 获取包括父类的所有字段
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                result.put(field.getName(), field.get(obj));
            }
            clazz = clazz.getSuperclass();  // 向上查找父类
        }
        return result;
    }
    /**
     * 复制对象属性
     */
    public static void copyFields(Object source, Object target) throws Exception {
        Class<?> sourceClass = source.getClass();
        Class<?> targetClass = target.getClass();
        Field[] sourceFields = sourceClass.getDeclaredFields();
        for (Field sourceField : sourceFields) {
            sourceField.setAccessible(true);
            try {
                Field targetField = targetClass.getDeclaredField(sourceField.getName());
                if (targetField.getType().equals(sourceField.getType())) {
                    targetField.setAccessible(true);
                    targetField.set(target, sourceField.get(source));
                }
            } catch (NoSuchFieldException e) {
                // 目标对象没有该字段,跳过
            }
        }
    }
}

注意事项

  1. 性能问题:反射操作比直接访问属性慢,频繁使用时需要考虑性能优化
  2. 安全检查:访问私有属性时需要调用 setAccessible(true)
  3. 异常处理:反射操作会抛出多种异常,需要适当处理
  4. 类型安全:反射绕过了编译时的类型检查,需要注意类型转换
  5. 线程安全:反射操作可能不是线程安全的

这些示例覆盖了Java反射获取属性的主要场景,可以根据实际需求选择合适的方式。

Java反射获取属性案例如何实现

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