java使用反射給對象屬性賦值的兩種方法
前言
最近項目中遇到一個問題,就是能實現(xiàn)一個類將以后的多語都進行轉(zhuǎn)換的通用方法,根據(jù)這個需求,決定使用反射實現(xiàn),根據(jù)反射給對象屬性設置屬性值,下面是使用反射實現(xiàn)對對象屬性值進行設置的方法
方法1:這里使用了Field的set方的 Field 屬性,然后設置可見性,然后設置了一個值,最后打印
// 給變量賦值 給object對象的某個字段賦值
f.set(object, value);
//拿到了Field類的實例后就可以調(diào)用其中的方法了
//方法: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例子,就設置了我們的最初的功能。
總結(jié):
也就是說,第一種方法,沒有調(diào)用屬性的set方法就完成了賦值,
但是第二種方法,是通過調(diào)用屬性的set方法來完成賦值。
所以,如果想在程序中改變程序的屬性的值的同時還想做一些額外的事情,可以將這些事情寫到set方法中并使用第二種方法
public class MultiLangContentUtil { /** * 從PO查詢數(shù)據(jù)賦值到DTO * 注意!!這里的多語字段根據(jù) * 簡體中文的變量名 英文名和繁體名需要根據(jù)規(guī)則進行 指定 * 規(guī)則如下 * 英文名=簡體中文名2 * 繁體名=簡體中文名3 * * @param targetPO 數(shù)據(jù)庫中查詢出的數(shù)據(jù) * @param targetDTO 將要轉(zhuǎn)換的對象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根據(jù)PO進行設置 declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO)); break; case EN_US: //獲取PO的值 Field declaredFieldPO2 = targetPOClass.getDeclaredField(targetMultiName + 2); //獲取DTO對象 declaredFieldPO2.setAccessible(true); //對DTO根據(jù)PO進行設置 declaredFieldDTO.set(targetDTO, declaredFieldPO2.get(targetPO)); break; case ZH_TW: //獲取PO的值 Field declaredFieldPO3 = targetPOClass.getDeclaredField(targetMultiName + 3); //獲取DTO對象 declaredFieldPO3.setAccessible(true); //對DTO根據(jù)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根據(jù)PO進行設置 declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO)); } } catch (NoSuchFieldException e) { log.error("查詢當前字段--->{}不存在{},", targetMultiName, e); } catch (IllegalAccessException e) { log.error("查詢字段--->{}多語時發(fā)生非法狀態(tài)異常{},", targetMultiName, e); } catch (Exception e) { log.error("查詢字段{}多語時發(fā)生錯誤{},", targetMultiName, e); } catch (Throwable throwable) { log.error("查詢多語言字段{}發(fā)生未知錯誤{}", targetMultiName, ThrowableUtil.stackTraceToString(throwable)); } } /** * 更新多語字段 * * @param targetDTO 需要轉(zhuǎn)換的字段 * @param targetPO 數(shù)據(jù)庫PO * @param fieldName 多語字段 * @param MultiLangSize 多語字段的數(shù)量 */ 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("更新字段--->{}多語時發(fā)生非法狀態(tài)異常{},", fieldName, e); } catch (Exception e) { log.error("更新字段{}多語時發(fā)生錯誤{},", fieldName, e); } catch (Throwable throwable) { log.error("更新多語言字段{}發(fā)生未知錯誤{}", 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類的實例后就可以調(diào)用其中的方法了
//方法:get(Object obj) 返回指定對象obj上此 Field 表示的字段的值
到此這篇關于java使用反射給對象屬性賦值的文章就介紹到這了,更多相關java反射給對象屬性賦值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決springboot與springcloud版本兼容問題(附版本兼容表)
在基于spring boot搭建spring cloud時,創(chuàng)建eureka后啟動服務發(fā)生報錯,本文給大家介紹了解決springboot與springcloud版本兼容問題的幾種方案,需要的朋友可以參考下2024-02-02利用Kotlin + Spring Boot實現(xiàn)后端開發(fā)
這篇文章主要給大家介紹了關于利用Kotlin + Spring Boot實現(xiàn)后端開發(fā)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-11-11詳解Spring緩存注解@Cacheable,@CachePut , @CacheEvict使用
這篇文章主要介紹了詳解Spring緩存注解@Cacheable,@CachePut , @CacheEvict使用,非常具有實用價值,需要的朋友可以參考下2017-05-05springboot使用之多個filter的執(zhí)行順序以及配置方式
這篇文章主要介紹了springboot使用之多個filter的執(zhí)行順序以及配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08spring boot與spring mvc的區(qū)別及功能介紹
這篇文章主要介紹了spring boot與spring mvc的區(qū)別是什么以及spring boot和spring mvc功能介紹,感興趣的朋友一起看看吧2018-02-02