利用反射機制實現物件轉Map集合
分析問題
問題主要有以下幾點
- 如何獲取物件中的屬性的名稱?
- 如何獲取物件的屬性值?如何這個屬性被private修飾,該如何處理?
- 返回的是一個物件該如何獲取物件的屬性引數呢?
解決問題
- 問題1:可以使用反射來獲取POJO物件的get方法(當然包括boolean型別的is方法),然後來處理成為屬性,主要邏輯是分析是否包以is或者get關鍵字開頭,如果是的話那麼返回處理後的資料資訊。轉換簡略程式碼如下:
/** * 處理方法,將get方法轉換為屬性名 * * @param methodName * @return */ public static String dealMethodName(String methodName) { StringBuilder stringBuilder = new StringBuilder(); if (methodName.startsWith("get")) { stringBuilder.append(methodName.toLowerCase().charAt(3)).append(methodName.substring(4)); } else if (methodName.startsWith("is")) { stringBuilder.append(methodName.toLowerCase().charAt(2)).append(methodName.substring(3)); } else { return methodName; } return stringBuilder.toString(); }
-
問題2:由於可以獲取到POJO物件的get方法,因此我們可執行這個方法來進行獲取到結果,從而也避免了private修飾的問題。
-
問題3:如果使用get方法獲取過來的是一個物件,那麼我們可以通過判斷是不是Object類來判斷是不是需要迭代處理,後來發現,在使用一些基礎資料類的時候,比如int,char,float等,他會自定的裝箱,從而導致我們無法處理,後來取了一個折中的辦法自定義了一個註解,在返回值是POJO物件的地方標註,在使用反射獲取get方法中獲取這個註解,如果註解是null說明不是POJO,如果不是null,那麼我們進行二次的迭代處理該物件,註解程式碼如下:
//作用於方法上,執行時保留
@Target(value={METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedIterative {
//引數沒有作用
String value() default "";
}
詳細程式碼
首先實現POJO類,POJO類主要程式碼如下所示<span style="color:red;">set方法已省略,自行補充,People類也是</span>,
public class Student{ private String name; private int age; private float height; private double weight; private char sex; private boolean allow; private People people; public Student(String name, int age, float height, double weight, char sex, boolean allow) { this.name = name; this.age = age; this.height = height; this.weight = weight; this.sex = sex; this.allow = allow; } public String getName() { return name;} public int getAge() { return age; } public float getHeight() { return height;} public double getWeight() {return weight;} public char getSex() {return sex;} public boolean isAllow() { return allow;} //此處添加了註解,說明此處返回的是一個POJO需要迭代處理 @NeedIterative public People getPeople() { return new People("李亞偉",12); }
需要返回的物件POJO物件是People類的程式碼內容為
public class People{
private String people;
private int work;
public People(String people, int work) {
this.people = people;
this.work = work;
}
public String getPeople() { return people; }
public int getWork() { return work; }
}
反射返回物件
程式碼很見到,都是Class等常見的API,這裡不做贅述。
public static Map toMap(Object obj) throws Exception {
Class clazz = obj.getClass();
//獲得屬性
Field[] fields = obj.getClass().getDeclaredFields();
HashMap hashMap = new HashMap(fields.length);
for (Field field : fields) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
//獲得get方法
Method getMethod = pd.getReadMethod();
//執行get方法返回一個Object
Object exeValue = getMethod.invoke(obj);
String key = dealMethodName(getMethod.getName());
NeedIterative annotation = getMethod.getAnnotation(NeedIterative.class);
//獲取的註解不為空,那麼說明此處返回的結果是物件,那麼需要迭代處理
if (annotation != null) {
exeValue = toMap(exeValue);
}
hashMap.put(key, exeValue);
}
return hashMap;
}
輸出結果
由此可見,不管是基本資料型別,還是POJO類都能正常的轉換。
斷點資料型別檢視:
sout輸出效果如下:
{
allow=true,
sex=m,
name=周濤,
weight=12.23,
people={
people=李亞偉,
work=12
},
age=23,
height=12.12
}
感興趣可以加Java架構師群獲取Java工程化、高效能及分散式、高效能、深入淺出。高架構。效能調優、Spring,MyBatis,Netty原始碼分析和大資料等多個知識點高階進階乾貨的直播免費學習許可權 都是大牛帶飛 讓你少走很多的彎路的 群..號是:855801563 對了 小白勿進 最好是有開發經驗
注:加群要求
1、具有工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的可以加。
2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以加。
3、如果沒有工作經驗,但基礎非常紮實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的,可以加。
4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的可以加。
5.阿里Java高階大牛直播講解知識點,分享知識,多年工作經驗的梳理和總結,帶著大家全面、科學地建立自己的技術體系和技術認知!