反射获取或修改对象属性的值

   利用反射既可以获取也可以写入,首先咱们先写几个获取的例子。

一:利用反射修改各数据(利用resultField.set修改)

首先定义实体类

public class Dog {
    private String dogUser;
    private int age;

DogUser"hahaha"改为"geggegegege"

Dog dog = new Dog();
dog.setAge(21);
dog.setDogUser("hahaha");
Object name = getValueByKey(dog, "dogUser");
System.out.println("获取到的属性名dogUser:"+name);

利用反射修改属性的工具类

public static <T> Object getValueByKey(T t, String key) {
        Class clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        Field resultField = Arrays.stream(fields)
                .filter(field -> field.getName().equals(key))
                .findFirst()
                .get();
        Object obj = null;
        resultField.setAccessible(true);
        try {
            //把dogUser属性值从hahaha改为geggegegege
            resultField.set(t,"geggegegege");
            obj = resultField.get(t);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }

测试结果:

在这里插入图片描述

二:利用反射获取各种形式的数据

首先定义实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Person {
 
    private String name = "zhangsan";
 
    private byte sex = 1;
 
    private int age = 18;
 
    private String introduce = "niuBility";
}

在定义一个接口常量

public interface Constant {
 
    int CONFIG_INT1 = 1;
 
    int CONFIG_INT2 = 2;
 
    int CONFIG_INT3 = 3;
 
    String CONFIG_STRING1 = "1";
 
    String CONFIG_STRING2 = "2";
 
    String CONFIG_STRING3 = "3";
}

1:获取单个对象的所有键值对(变量名-变量值)

   通过泛型参数限定传入一个对象,该方法传入一个对象,返回该对象所有的属性-值。

   注意:这里Collectors.toMap(key,value)中的value值不能为空,若对象属性值存在为空的情况,则会抛出空指针异常,查看toMap()方法源码,发现在map集合进行merge合并时进行了非空判断操作,如下:
在这里插入图片描述

   故这里使用Optional进行空值的包装,在为空时用0代替(看具体业务场景)。ps: 做map转换记得写键值冲突策略,养成好习惯,这里采用后者覆盖,(k1, k2) -> k2。

/**
     * 获取单个对象的所有键值对
     *
     * @param t
     * @param <T>
     * @return
     */
    public static <T> Map<String, Object> getKeyAndValue(T t) {
        Map<String, Object> map = Maps.newHashMap();
        Class clazz = (Class) t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        map = Arrays.stream(fields).collect(Collectors.toMap(Field::getName, field -> {
            Object resultObj = null;
            field.setAccessible(true);
            try {
                resultObj = field.get(t);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return Optional.ofNullable(resultObj).orElse(0);
        }, (k1, k2) -> k2));
        return map;
    }

测试用例:

Map<String, Object> result1 = ReflectObjectUtil.getKeyAndValue(new Person());

测试结果:
在这里插入图片描述
2:获取单个对象指定键的值

第一种方式:

/**
     * 获取单个对象指定键的值
     *
     * @param t
     * @param key
     * @param <T>
     * @return
     */
    public static <T> Object getValueByKey(T t, String key) {
        Class clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        Field resultField = Arrays.stream(fields)
                .filter(field -> field.getName().equals(key))
                .findFirst()
                .get();
        Object obj = null;
        resultField.setAccessible(true);
        try {
            obj = resultField.get(t);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }

测试用例:

Object result2 = ReflectObjectUtil.getValueByKey(new Person(), "name");

测试结果:

在这里插入图片描述

第二种方式(利用反射Method的invoke方法):

实体类:

public class Dog{
    private String name;
    private int age;
Dog dog = new Dog();
dog.setAge(21);
dog.setName("哈哈");
//第二种方式
Object name = getFieldValueByName("name", (Object) dog);
System.out.println("获取到的属性名:"+name);
public static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[] {});
            Object value = method.invoke(o, new Object[] {});
            return value;
        } catch (Exception e) {
            return null;
        }
    }

测试结果:

在这里插入图片描述

3:获取多个对象的所有键值对

/**
     * 获取多个对象的所有键值对
     *
     * @param objects
     * @return
     */
    public static List<Map<String, Object>> getKeyAndValues(List<Object> objects) {
        return objects.stream().map(obj -> {
            Class clazz = obj.getClass();
            return Arrays.stream(clazz.getDeclaredFields()).collect(Collectors.toMap(Field::getName, field -> {
                Object resultObj = null;
                field.setAccessible(true);
                try {
                    resultObj = field.get(obj);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                return Optional.ofNullable(resultObj).orElse(0);
            }, (k1, k2) -> k2));
        }).collect(Collectors.toList());
    }

测试用例:

List<Map<String, Object>> result3 = ReflectObjectUtil.getKeyAndValues(Arrays.asList(new Person(), new Person()));

测试结果:

在这里插入图片描述

4:获取多个对象指定键的所有值

/**
     * 获取多个对象指定键的所有值
     *
     * @param objects
     * @param key
     * @return
     */
    public static List<Object> getValuesByKey(List<Object> objects, String key) {
        return objects.stream().map(obj -> {
            Class clazz = obj.getClass();
            return Arrays.stream(clazz.getDeclaredFields())
                    .filter(field -> field.getName().equals(key))
                    .map(field -> {
                        Object resultObj = null;
                        field.setAccessible(true);
                        try {
                            resultObj = field.get(obj);
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                        return resultObj;
                    }).collect(Collectors.toList());
        }).collect(Collectors.toList());
    }

测试用例:

List<Object> result4 = ReflectObjectUtil.getValuesByKey(Arrays.asList(new Person(), new Person()), "name");

测试结果:

在这里插入图片描述

5:获取静态变量(以下适用与类或接口参数)

/**
     * 获取静态变量
     *
     * @param clazz
     * @param key
     * @return
     */
    public static Object getValueByKey(Class<?> clazz, String key) {
        Field[] fields = clazz.getDeclaredFields();
        Field result = Arrays.stream(fields)
                .filter(field -> key.equals(field.getName()))
                .findFirst()
                .get();
        Object obj = null;
        try {
            obj = clazz.getField(result.getName()).get(null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return obj;
    }

测试用例:

String result5 = ReflectObjectUtil.getValueByKey(Constant.class, "CONFIG_INT1").toString();

测试结果:

在这里插入图片描述

6:获取类或接口中所有的常量

 /**
     * 获取类或接口中所有的常量
     *
     * @param clazz
     * @return
     */
    public static Map<String, Object> getFinalValues(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        return Arrays.stream(fields)
                .filter(field -> Modifier.isFinal(field.getModifiers()))
                .collect(Collectors.toMap(Field::getName, field -> {
                    Object obj = null;
                    try {
                        obj = clazz.getField(field.getName()).get(null);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (NoSuchFieldException e) {
                        e.printStackTrace();
                    }
                    return obj;
                }));
    }

测试用例:

Map<String, Object> result6 = ReflectObjectUtil.getFinalValues(Constant.class);

测试结果:

在这里插入图片描述

测试用例汇总:

public class Test1 {
    public static void main(String[] args) {
        Map<String, Object> result1 = ReflectObjectUtil.getKeyAndValue(new Person());
        Object result2 = ReflectObjectUtil.getValueByKey(new Person(), "name");
        List<Map<String, Object>> result3 = ReflectObjectUtil.getKeyAndValues(Arrays.asList(new Person(), new Person()));
        List<Object> result4 = ReflectObjectUtil.getValuesByKey(Arrays.asList(new Person(), new Person()), "name");
        String result5 = ReflectObjectUtil.getValueByKey(Constant.class, "CONFIG_INT1").toString();
        Map<String, Object> result6 = ReflectObjectUtil.getFinalValues(Constant.class);
    }
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java反射是指在程序运行的时候,通过特定的API来检查或修改程序的状态、能力和内部属性等,而这些在正常情况下是无法通过编译时检查来完成的。例如,通过反射机制,我们可以获取一个对象的类型信息并调用其方法、访问它的属性,以及创建一个新对象等。 反射获取对象属性,首先需要通过Class类的forName()方法来获取对象的Class实例。然后通过Class类的getDeclaredField()方法获取对象属性的Field对象,再通过Field对象的get()方法来获取属性。如果需要获取私有属性,则需要通过setAccessible(true)方法来取消Java语言的访问检查机制,以允许获取私有属性。 例如,假设有一个Person类,其中包含有一个private String name属性,现在需要获取属性,可以使用反射机制进行如下操作: ``` Class<?> clazz = Person.class; Object obj = clazz.newInstance(); Field field = clazz.getDeclaredField("name"); field.setAccessible(true); String nameValue = (String) field.get(obj); ``` 通过以上代码,我们可以获取Person对象的name属性,并将其赋给nameValue变量中。 需要注意的是,反射机制虽然功能强大,但由于它会在运行时改变程序的状态和能力,因此会带来诸多安全性和性能上的问题,尤其是容易引起类型转换异常和内存泄漏等问题,因此在使用反射机制时要谨慎操作,避免不必要的风险。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值