• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

java使用反射把对象属性赋值

武飞扬头像
HiSiri666666
帮助1

📢 📢 📢 📣 📣 📣
哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步 🤝 🤝
一位上进心十足的【Java ToB端大厂领域博主】! 😜 😜 😜
喜欢java和python,平时比较懒,能用程序解决的坚决不手动解决 😜 😜 😜

✨ 如果有对【java】感兴趣的【小可爱】,欢迎关注我
❤️ ❤️ ❤️感谢各位大可爱小可爱! ❤️ ❤️ ❤️
————————————————
如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。

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

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

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

f.set(object, value);

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

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

  1.  
    package com.example.reflectiondemo;
  2.  
     
  3.  
    import java.lang.reflect.Field;
  4.  
     
  5.  
    /**
  6.  
    * @program my-project-model
  7.  
    * @description:
  8.  
    * @author: lee
  9.  
    * @create: 2023/01/04 19:52
  10.  
    */
  11.  
    public class ReflectMain {
  12.  
     
  13.  
    private String readOnly;
  14.  
     
  15.  
    public String getReadOnly() {
  16.  
    return readOnly;
  17.  
    }
  18.  
     
  19.  
    public void setReadOnly(String readOnly) {
  20.  
    System.out.println("set");
  21.  
    this.readOnly = readOnly;
  22.  
    }
  23.  
     
  24.  
     
  25.  
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
  26.  
    ReflectMain t = new ReflectMain();
  27.  
    Field f = t.getClass().getDeclaredField("readOnly");
  28.  
    f.setAccessible(true);
  29.  
    f.set(t, "test");
  30.  
    System.out.println(t.getReadOnly());
  31.  
     
  32.  
    }
  33.  
    }
学新通

方法2:使用invoke方法

  1.  
    package com.example.reflectiondemo;
  2.  
     
  3.  
    import java.lang.reflect.Field;
  4.  
    import java.lang.reflect.InvocationTargetException;
  5.  
    import java.lang.reflect.Method;
  6.  
     
  7.  
    /**
  8.  
    * @program my-project-model
  9.  
    * @description:
  10.  
    * @author: lee
  11.  
    * @create: 2023/01/04 19:52
  12.  
    */
  13.  
    public class ReflectMain {
  14.  
     
  15.  
    private String readOnly;
  16.  
     
  17.  
    public String getReadOnly() {
  18.  
    return readOnly;
  19.  
    }
  20.  
     
  21.  
    public void setReadOnly(String readOnly) {
  22.  
    System.out.println("set");
  23.  
    this.readOnly = readOnly;
  24.  
    }
  25.  
     
  26.  
     
  27.  
    // public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
  28.  
    // ReflectMain t = new ReflectMain();
  29.  
    // Field f = t.getClass().getDeclaredField("readOnly");
  30.  
    // f.setAccessible(true);
  31.  
    // f.set(t, "test");
  32.  
    // System.out.println(t.getReadOnly());
  33.  
    //
  34.  
    // }
  35.  
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
  36.  
    ReflectMain t = new ReflectMain();
  37.  
    Method setReadOnly = t.getClass().getMethod("setReadOnly", String.class);
  38.  
    String s = "test2";
  39.  
    setReadOnly.invoke(t, s);
  40.  
    System.out.println(t.getReadOnly());
  41.  
     
  42.  
    }
  43.  
     
  44.  
    }
学新通
学新通

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

总结:

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

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

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

  1.  
    public class MultiLangContentUtil {
  2.  
     
  3.  
    /**
  4.  
    * 从PO查询数据赋值到DTO
  5.  
    * 注意!!这里的多语字段根据
  6.  
    * 简体中文的变量名 英文名和繁体名需要根据规则进行 指定
  7.  
    * 规则如下
  8.  
    * 英文名=简体中文名2
  9.  
    * 繁体名=简体中文名3
  10.  
    *
  11.  
    * @param targetPO 数据库中查询出的数据
  12.  
    * @param targetDTO 将要转换的对象DTO
  13.  
    * @param targetMultiName 需要展示的多语字段
  14.  
    * @throws NoSuchFieldException
  15.  
    * @throws IllegalAccessException
  16.  
    */
  17.  
    public static void setMultiLangDTOName(Object targetPO, Object targetDTO, String targetMultiName) {
  18.  
    try {
  19.  
     
  20.  
    String locale = MultiLangContentUtil.getLocale();
  21.  
    Class<?> targetDTOClass = targetDTO.getClass();
  22.  
    Class<?> targetPOClass = targetPO.getClass();
  23.  
    //这里是将targetMultiName进行展示
  24.  
    Field declaredFieldDTO = targetDTOClass.getDeclaredField(targetMultiName);
  25.  
    declaredFieldDTO.setAccessible(true);
  26.  
    switch (locale) {
  27.  
    case ZH_CN:
  28.  
    //获取PO的值
  29.  
    Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName);
  30.  
    //获取DTO对象
  31.  
    declaredFieldPO.setAccessible(true);
  32.  
    //对DTO根据PO进行设置
  33.  
    declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO));
  34.  
    break;
  35.  
    case EN_US:
  36.  
    //获取PO的值
  37.  
    Field declaredFieldPO2 = targetPOClass.getDeclaredField(targetMultiName 2);
  38.  
    //获取DTO对象
  39.  
    declaredFieldPO2.setAccessible(true);
  40.  
    //对DTO根据PO进行设置
  41.  
    declaredFieldDTO.set(targetDTO, declaredFieldPO2.get(targetPO));
  42.  
    break;
  43.  
    case ZH_TW:
  44.  
    //获取PO的值
  45.  
    Field declaredFieldPO3 = targetPOClass.getDeclaredField(targetMultiName 3);
  46.  
    //获取DTO对象
  47.  
    declaredFieldPO3.setAccessible(true);
  48.  
    //对DTO根据PO进行设置
  49.  
    declaredFieldDTO.set(targetDTO, declaredFieldPO3.get(targetPO));
  50.  
    break;
  51.  
    default:
  52.  
    break;
  53.  
    }
  54.  
    //防止没有抽取多语的情况下没有参照返回,默认情况下设置中文
  55.  
    if (StringUtils.isBlank((String) declaredFieldDTO.get(targetDTO))) {
  56.  
    //获取PO的值
  57.  
    Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName);
  58.  
    //获取DTO对象
  59.  
    declaredFieldPO.setAccessible(true);
  60.  
    //对DTO根据PO进行设置
  61.  
    declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO));
  62.  
    }
  63.  
    } catch (NoSuchFieldException e) {
  64.  
    log.error("查询当前字段--->{}不存在{},", targetMultiName, e);
  65.  
    } catch (IllegalAccessException e) {
  66.  
    log.error("查询字段--->{}多语时发生非法状态异常{},", targetMultiName, e);
  67.  
    } catch (Exception e) {
  68.  
    log.error("查询字段{}多语时发生错误{},", targetMultiName, e);
  69.  
    } catch (Throwable throwable) {
  70.  
    log.error("查询多语言字段{}发生未知错误{}", targetMultiName, ThrowableUtil.stackTraceToString(throwable));
  71.  
    }
  72.  
    }
  73.  
     
  74.  
    /**
  75.  
    * 更新多语字段
  76.  
    *
  77.  
    * @param targetDTO 需要转换的字段
  78.  
    * @param targetPO 数据库PO
  79.  
    * @param fieldName 多语字段
  80.  
    * @param MultiLangSize 多语字段的数量
  81.  
    */
  82.  
    public static void updateMultiLang(Object targetDTO, Object targetPO, String fieldName, Integer MultiLangSize) {
  83.  
    try {
  84.  
    Class<?> targetDTOClass = targetDTO.getClass();
  85.  
    Class<?> targetPOClass = targetPO.getClass();
  86.  
     
  87.  
    Field dtoClassField = targetDTOClass.getDeclaredField(fieldName);
  88.  
    dtoClassField.setAccessible(true);
  89.  
    if (StringUtils.isNotBlank((String) dtoClassField.get(targetDTO))) {
  90.  
    Field poClassField = targetPOClass.getDeclaredField(fieldName);
  91.  
    poClassField.setAccessible(true);
  92.  
    poClassField.set(targetPO, dtoClassField.get(targetDTO));
  93.  
    }
  94.  
    for (int i = 2; i <= MultiLangSize; i ) {
  95.  
    Field dtoClassField2 = targetDTOClass.getDeclaredField(fieldName i);
  96.  
    dtoClassField2.setAccessible(true);
  97.  
    if (StringUtils.isNotBlank((String) dtoClassField2.get(targetDTO))) {
  98.  
    Field poClassField2 = targetPOClass.getDeclaredField(fieldName i);
  99.  
    poClassField2.setAccessible(true);
  100.  
    poClassField2.set(targetPO, dtoClassField2.get(targetDTO));
  101.  
    }
  102.  
    }
  103.  
    } catch (NoSuchFieldException e) {
  104.  
    log.error("更新当前字段--->{}不存在{},", fieldName, e);
  105.  
    } catch (IllegalAccessException e) {
  106.  
    log.error("更新字段--->{}多语时发生非法状态异常{},", fieldName, e);
  107.  
    } catch (Exception e) {
  108.  
    log.error("更新字段{}多语时发生错误{},", fieldName, e);
  109.  
    } catch (Throwable throwable) {
  110.  
    log.error("更新多语言字段{}发生未知错误{}", fieldName, ThrowableUtil.stackTraceToString(throwable));
  111.  
    }
  112.  
    }
  113.  
     
  114.  
    /**
  115.  
    * 获取本地的语言,默认中文
  116.  
    * en_US 英文
  117.  
    * zh_CN 简体中文
  118.  
    * zh_TW 繁体中文
  119.  
    *
  120.  
    * @return
  121.  
    */
  122.  
    public static final String getLocale() {
  123.  
    String locale = InvocationInfoProxy.getLocale();
  124.  
    return StringUtils.isEmpty(locale) ? "zh_CN" : locale;
  125.  
    }
  126.  
    }
学新通

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

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

  • Field的set方法设置属性

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

f.set(object, value);

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

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

学新通

如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggajeg
系列文章
更多 icon
同类精品
更多 icon
继续加载