利用反射操作bean的属性和方法
今天在開(kāi)發(fā)中碰到這樣一個(gè)場(chǎng)景:當(dāng)請(qǐng)求添加項(xiàng)目下的目錄時(shí),傳過(guò)來(lái)的是一個(gè)IndexModel,這個(gè)Model里有關(guān)于這個(gè)目錄字段的詳細(xì)信息,包括基礎(chǔ)報(bào)表,實(shí)時(shí),漏斗等信息(這些字段類型都是boolean),對(duì)應(yīng)于頁(yè)面上生成目錄的多選框。現(xiàn)要將這些配置存入數(shù)據(jù)庫(kù),在數(shù)據(jù)庫(kù)中存的是這個(gè)項(xiàng)目下的目錄,比如說(shuō)在頁(yè)面勾選了基礎(chǔ)報(bào)表這個(gè)選擇框,就會(huì)在數(shù)據(jù)庫(kù)中的menu表插入一條數(shù)據(jù)記錄這個(gè)配置。這樣一來(lái),就需要對(duì)傳遞過(guò)來(lái)的這個(gè)IndexModel類的屬性值進(jìn)行判斷,再?zèng)Q定插入數(shù)據(jù)庫(kù)的信息。
? ? 下面是IndexModel這個(gè)model的基本屬性:
1 public class IndexModel { 2 private Boolean basic_report; //基礎(chǔ)報(bào)表 3 private Boolean realtime; //實(shí)時(shí) 4 private Boolean event; //事件 5 private Boolean retain;// 留存 6 private Boolean funnel; //漏斗 7 private Boolean explore; //探索 8 private Boolean grouping; //分組 9 private Boolean user_portrait; //用戶畫像 10 private Boolean log; //日志 11 12 //setters and getters .. 13 }當(dāng)某個(gè)屬性為true時(shí),則就會(huì)將這個(gè)屬性配置進(jìn)數(shù)據(jù)庫(kù),當(dāng)這個(gè)屬性為false時(shí),則不會(huì)進(jìn)行任何操作。
由此,我想到了利用Java反射,遍歷這個(gè)類的屬性,然后獲取到這個(gè)屬性的名字和值判斷,再映射成數(shù)據(jù)庫(kù)表的字段,插入到數(shù)據(jù)庫(kù)中去。
?我們先上解決方案代碼:
1 Field[] fields = IndexModel.class.getDeclaredFields(); 2 for (int i = 0; i < fields.length; i++) { 3 Field f = fields[i]; 4 f.setAccessible(true); // 設(shè)置這些屬性是可以訪問(wèn)的 5 try { 6 if(f.getGenericType().toString().endsWith("Boolean") && (Boolean) f.get(indexModel) == true) { // 得到此屬性的值 7 IndexDto indexDto = parseIndexModelToDto(indexModel, f.getName()); 8 projectService.addIndex(indexDto); 9 } 10 } catch (IllegalAccessException e) { 11 logger.error("屬性類型轉(zhuǎn)換異常"); 12 } 13 }在代碼中先是利用反射獲取類的所有對(duì)象成員的字段值,在這里由于IndexModel中的屬性字段值都是private的,所以,只能使用?getDeclaredFields()獲取到這些字段,至于getFields()方法,只能獲取到類(及其父類)中的公有成員,這兩個(gè)方法返回的都是Field類型的數(shù)組。
在獲取私有成員值之前,必須調(diào)用setAccessible(true),否則的話,將會(huì)拋出異常:java.lang.IllegalAccessException: ?class... can?not?access ,顯示不能獲取字段值。
另外,在需要獲取成員的類型時(shí),需要調(diào)用相應(yīng)的field的getType()方法,獲取field的類型有如下幾種方法
?
1 Class<?> type = field.getType(); // 通過(guò)這種方式只對(duì)普通類型的Field有效,如果該Field的類型是有泛型限制的類型,如Map<String,Integer>類型,則不能準(zhǔn)確得到該Field的泛型參數(shù)。 2 3 Type type = field.getGenericType(); // 為了獲得指定Field的泛型類型,應(yīng)該使用這個(gè)方法來(lái)獲取指定Field的泛型類型如果要獲取上面對(duì)應(yīng)field的被泛型限制的方法,就需要將上面的type對(duì)象強(qiáng)制類型轉(zhuǎn)換成ParameterizedType對(duì)象,ParameterizedType代表被參數(shù)化的類型,也就是增加了泛型限制的類型,ParameterizedType類提供了兩個(gè)方法:
??? getRawType(); ? ? ? ? ? ? ? ? ? ? ? ? ? ?返回被泛型限制的類型;
??? getActualTypeArguments(); ? ? ? ?返回泛型參數(shù)類型。 ??
然后,要獲取成員變量的名稱直接使用field.getName(),但是屬性值則是field.get(Object),這個(gè)object是該field所屬的!
最后,要是想為這個(gè)成員變量設(shè)置值,則需要調(diào)用set:field[i].set(indexModel , true);
轉(zhuǎn)載于:https://www.cnblogs.com/jy107600/p/7150976.html
總結(jié)
以上是生活随笔為你收集整理的利用反射操作bean的属性和方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 专题——背包问题
- 下一篇: Solidworks如何将参考平面的图形