java使用反射给对象属性赋值的两种方法

作者:奇点_97

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,下面这篇文章主要给大家介绍了关于java使用反射给对象属性赋值的两种方法,需要的朋友可以参考下

最近项目中遇到一个问题,就是能实现一个类将以后的多语都进行转换的通用方法,根据这个需求,决定使用反射实现,根据反射给对象属性设置属性值,下面是使用反射实现对对象属性值进行设置的方法

方法1:这里使用了Field的set方的 Field 属性,然后设置可见性,然后设置了一个值,最后打印

// 给变量赋值 给object对象的某个字段赋值

f.set(object, value);

//拿到了Field类的实例后就可以调用其中的方法了

//方法:get(Object obj) 返回指定对象obj上此 Field 表示的字段的值

package com.example.reflectiondemo;
import java.lang.reflect.Field;
 * @program my-project-model
 * @description:
 * @author: lee
 * @create: 2023/01/04 19:52
public class ReflectMain {
    private String readOnly;
    public String getReadOnly() {
        return readOnly;
    public void setReadOnly(String readOnly) {
        System.out.println("set");
        this.readOnly = readOnly;
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        ReflectMain t = new ReflectMain();
        Field f = t.getClass().getDeclaredField("readOnly");
        f.setAccessible(true);
        f.set(t, "test");
        System.out.println(t.getReadOnly());

方法2:使用invoke方法

package com.example.reflectiondemo;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 * @program my-project-model
 * @description:
 * @author: lee
 * @create: 2023/01/04 19:52
public class ReflectMain {
    private String readOnly;
    public String getReadOnly() {
        return readOnly;
    public void setReadOnly(String readOnly) {
        System.out.println("set");
        this.readOnly = readOnly;
    //    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
//        ReflectMain t = new ReflectMain();
//        Field f = t.getClass().getDeclaredField("readOnly");
//        f.setAccessible(true);
//        f.set(t, "test");
//        System.out.println(t.getReadOnly());
//    }
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ReflectMain t = new ReflectMain();
        Method setReadOnly = t.getClass().getMethod("setReadOnly", String.class);
        String s = "test2";
        setReadOnly.invoke(t, s);
        System.out.println(t.getReadOnly());

由此可见,使用反射我们能给很容易的给各个属性进行设置,即使是private的属性我们也能很轻松的设置属性值,下面利用这个demo例子,就设置了我们的最初的功能。

也就是说,第一种方法,没有调用属性的set方法就完成了赋值,

但是第二种方法,是通过调用属性的set方法来完成赋值。

所以,如果想在程序中改变程序的属性的值的同时还想做一些额外的事情,可以将这些事情写到set方法中并使用第二种方法

public class MultiLangContentUtil {
     * 从PO查询数据赋值到DTO
     * 注意!!这里的多语字段根据
     * 简体中文的变量名 英文名和繁体名需要根据规则进行 指定
     * 规则如下
     * 英文名=简体中文名2
     * 繁体名=简体中文名3
     * @param targetPO        数据库中查询出的数据
     * @param targetDTO       将要转换的对象DTO
     * @param targetMultiName 需要展示的多语字段
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
    public static void setMultiLangDTOName(Object targetPO, Object targetDTO, String targetMultiName) {
        try {
            String locale = MultiLangContentUtil.getLocale();
            Class<?> targetDTOClass = targetDTO.getClass();
            Class<?> targetPOClass = targetPO.getClass();
            //这里是将targetMultiName进行展示
            Field declaredFieldDTO = targetDTOClass.getDeclaredField(targetMultiName);
            declaredFieldDTO.setAccessible(true);
            switch (locale) {
                case ZH_CN:
                    //获取PO的值
                    Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName);
                    //获取DTO对象
                    declaredFieldPO.setAccessible(true);
                    //对DTO根据PO进行设置
                    declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO));
                    break;
                case EN_US:
                    //获取PO的值
                    Field declaredFieldPO2 = targetPOClass.getDeclaredField(targetMultiName + 2);
                    //获取DTO对象
                    declaredFieldPO2.setAccessible(true);
                    //对DTO根据PO进行设置
                    declaredFieldDTO.set(targetDTO, declaredFieldPO2.get(targetPO));
                    break;
                case ZH_TW:
                    //获取PO的值
                    Field declaredFieldPO3 = targetPOClass.getDeclaredField(targetMultiName + 3);
                    //获取DTO对象
                    declaredFieldPO3.setAccessible(true);
                    //对DTO根据PO进行设置
                    declaredFieldDTO.set(targetDTO, declaredFieldPO3.get(targetPO));
                    break;
                default:
                    break;
            //防止没有抽取多语的情况下没有参照返回,默认情况下设置中文
            if (StringUtils.isBlank((String) declaredFieldDTO.get(targetDTO))) {
                //获取PO的值
                Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName);
                //获取DTO对象
                declaredFieldPO.setAccessible(true);
                //对DTO根据PO进行设置
                declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO));
        } catch (NoSuchFieldException e) {
            log.error("查询当前字段--->{}不存在{},", targetMultiName, e);
        } catch (IllegalAccessException e) {
            log.error("查询字段--->{}多语时发生非法状态异常{},", targetMultiName, e);
        } catch (Exception e) {
            log.error("查询字段{}多语时发生错误{},", targetMultiName, e);
        } catch (Throwable throwable) {
            log.error("查询多语言字段{}发生未知错误{}", targetMultiName, ThrowableUtil.stackTraceToString(throwable));
     * 更新多语字段
     * @param targetDTO     需要转换的字段
     * @param targetPO      数据库PO
     * @param fieldName     多语字段
     * @param MultiLangSize 多语字段的数量
    public static void updateMultiLang(Object targetDTO, Object targetPO, String fieldName, Integer MultiLangSize) {
        try {
            Class<?> targetDTOClass = targetDTO.getClass();
            Class<?> targetPOClass = targetPO.getClass();
            Field dtoClassField = targetDTOClass.getDeclaredField(fieldName);
            dtoClassField.setAccessible(true);
            if (StringUtils.isNotBlank((String) dtoClassField.get(targetDTO))) {
                Field poClassField = targetPOClass.getDeclaredField(fieldName);
                poClassField.setAccessible(true);
                poClassField.set(targetPO, dtoClassField.get(targetDTO));
            for (int i = 2; i <= MultiLangSize; i++) {
                Field dtoClassField2 = targetDTOClass.getDeclaredField(fieldName + i);
                dtoClassField2.setAccessible(true);
                if (StringUtils.isNotBlank((String) dtoClassField2.get(targetDTO))) {
                    Field poClassField2 = targetPOClass.getDeclaredField(fieldName + i);
                    poClassField2.setAccessible(true);
                    poClassField2.set(targetPO, dtoClassField2.get(targetDTO));
        } catch (NoSuchFieldException e) {
            log.error("更新当前字段--->{}不存在{},", fieldName, e);
        } catch (IllegalAccessException e) {
            log.error("更新字段--->{}多语时发生非法状态异常{},", fieldName, e);
        } catch (Exception e) {
            log.error("更新字段{}多语时发生错误{},", fieldName, e);
        } catch (Throwable throwable) {
            log.error("更新多语言字段{}发生未知错误{}", fieldName, ThrowableUtil.stackTraceToString(throwable));
     * 获取本地的语言,默认中文
     * en_US  英文
     * zh_CN  简体中文
     * zh_TW  繁体中文
     * @return
    public static final String getLocale() {
        String locale = InvocationInfoProxy.getLocale();
        return StringUtils.isEmpty(locale) ? "zh_CN" : locale;

这个工具类的核心思想就是

  • 使用Field的get方法获取属性值
  • Field的set方法设置属性

// 给变量赋值 给object对象的某个字段赋值

f.set(object, value);

//拿到了Field类的实例后就可以调用其中的方法了

//方法:get(Object obj) 返回指定对象obj上此 Field 表示的字段的值

到此这篇关于java使用反射给对象属性赋值的文章就介绍到这了,更多相关java反射给对象属性赋值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
  • web.xml SpringBoot打包可执行Jar运行SpringMVC加载流程
    web.xml SpringBoot打包可执行Jar运行SpringMVC加载流程
    2023-04-04
  • Java springboot 配置文件与多环境配置与运行优先级
    Java springboot 配置文件与多环境配置与运行优先级
    2023-04-04
  • mybatis日志打印的两款IDEA插件推荐
    mybatis日志打印的两款IDEA插件推荐
    2023-04-04
  • 4个Java8中你需要知道的函数式接口分享
    4个Java8中你需要知道的函数式接口分享
    2023-04-04
  • java使用反射给对象属性赋值的两种方法
    java使用反射给对象属性赋值的两种方法
    2023-04-04
  • Java中字符串常见的一些拼接方式总结
    Java中字符串常见的一些拼接方式总结
    2023-04-04
  • java中多个@Scheduled定时器不执行的解决方法
    java中多个@Scheduled定时器不执行的解决方法
    2023-04-04
  • idea中如何使用git进行版本回退详解
    idea中如何使用git进行版本回退详解
    2023-04-04
  • 美国设下计谋,用娘炮文化重塑日本,已影响至中国
    美国设下计谋,用娘炮文化重塑日本,已影响至中国
    2021-11-19
  • 时空伴随者是什么意思?时空伴随者介绍
    时空伴随者是什么意思?时空伴随者介绍
    2021-11-09
  • 工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    2021-11-05
  • 2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2021-10-26
  • 电脑版 - 返回首页

    2006-2023 脚本之家 JB51.Net , All Rights Reserved.
    苏ICP备14036222号