杰瑞科技汇

Java反射如何获取类的属性属性?

Java 反射获取类的属性

在 Java 中,反射机制允许程序在运行时检查和操作类、方法、字段等,以下是使用反射获取类属性(字段)的几种方法:

基本方法获取所有字段

import java.lang.reflect.Field;
public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // 获取Class对象
            Class<?> clazz = MyClass.class;
            // 获取所有声明的字段(包括私有字段)
            Field[] fields = clazz.getDeclaredFields();
            // 遍历字段
            for (Field field : fields) {
                System.out.println("字段名: " + field.getName());
                System.out.println("字段类型: " + field.getType());
                System.out.println("修饰符: " + java.lang.reflect.Modifier.toString(field.getModifiers()));
                System.out.println("----------------------");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class MyClass {
    private int id;
    public String name;
    protected double price;
    boolean available;
}

获取特定字段

// 获取特定名称的字段
try {
    Field idField = clazz.getDeclaredField("id");
    System.out.println("找到字段: " + idField.getName());
} catch (NoSuchFieldException e) {
    System.out.println("未找到该字段");
}

获取父类字段

// 获取所有字段(包括继承的)
Field[] allFields = clazz.getFields(); // 只能获取public字段
// 或者递归获取父类字段
Field[] allFields = getAllFields(clazz);
private static Field[] getAllFields(Class<?> clazz) {
    List<Field> fields = new ArrayList<>();
    while (clazz != null) {
        fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        clazz = clazz.getSuperclass();
    }
    return fields.toArray(new Field[0]);
}

获取字段值

MyClass obj = new MyClass();
obj.name = "测试";
try {
    Field nameField = clazz.getDeclaredField("name");
    // 设置可访问(即使字段是私有的)
    nameField.setAccessible(true);
    // 获取字段值
    Object value = nameField.get(obj);
    System.out.println("字段值: " + value);
} catch (Exception e) {
    e.printStackTrace();
}

设置字段值

try {
    Field priceField = clazz.getDeclaredField("price");
    priceField.setAccessible(true);
    // 设置字段值
    priceField.set(obj, 99.99);
    System.out.println("设置后的价格: " + obj.getPrice());
} catch (Exception e) {
    e.printStackTrace();
}

注意事项

  1. 访问控制:默认情况下,反射不能访问私有字段,需要调用 setAccessible(true) 来解除访问限制
  2. 性能:反射操作比直接访问慢,应避免在性能敏感的代码中频繁使用
  3. 安全性:反射可以绕过访问控制,可能破坏封装性
  4. 类型安全:反射操作需要处理类型检查和转换

实用工具方法

public class ReflectionUtils {
    /**
     * 获取对象的所有字段名和值
     */
    public static Map<String, Object> getFieldValues(Object obj) {
        Map<String, Object> values = new HashMap<>();
        if (obj == null) return values;
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object value = field.get(obj);
                values.put(field.getName(), value);
            } catch (IllegalAccessException e) {
                values.put(field.getName(), "[无法访问]");
            }
        }
        return values;
    }
}

使用示例:

MyClass obj = new MyClass();
obj.name = "测试";
obj.price = 99.99;
Map<String, Object> values = ReflectionUtils.getFieldValues(obj);
System.out.println(values);

反射是Java强大的特性,但应谨慎使用,遵循"在必要时才使用"的原则。

分享:
扫描分享到社交APP
上一篇
下一篇