利用反射機(jī)制實(shí)現(xiàn)對(duì)象轉(zhuǎn)Map集合

更多關(guān)于Java方面的文章,歡迎訪(fǎng)問(wèn)燕歸來(lái)https://www.zhoutao123.com

前不久有個(gè)需求,實(shí)現(xiàn)對(duì)象轉(zhuǎn)換為map,這里思考了一些,沒(méi)有用別人的輪子,自己實(shí)現(xiàn)了這個(gè)需求,寫(xiě)了一個(gè)簡(jiǎn)單的工具類(lèi)來(lái)做這個(gè)。

分析問(wèn)題

問(wèn)題主要有以下幾點(diǎn)

  • 如何獲取對(duì)象中的屬性的名稱(chēng)?
  • 如何獲取對(duì)象的屬性值?如何這個(gè)屬性被private修飾,該如何處理?
  • 返回的是一個(gè)對(duì)象該如何獲取對(duì)象的屬性參數(shù)呢?

解決問(wèn)題

  • 問(wèn)題1:可以使用反射來(lái)獲取POJO對(duì)象的get方法(當(dāng)然包括boolean類(lèi)型的is方法),然后來(lái)處理成為屬性,主要邏輯是分析是否包以is或者get關(guān)鍵字開(kāi)頭,如果是的話(huà)那么返回處理后的數(shù)據(jù)信息。轉(zhuǎn)換簡(jiǎn)略代碼如下:
 /**
     * 處理方法,將get方法轉(zhuǎn)換為屬性名
     *
     * @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();
    }
  • 問(wèn)題2:由于可以獲取到POJO對(duì)象的get方法,因此我們可執(zhí)行這個(gè)方法來(lái)進(jìn)行獲取到結(jié)果,從而也避免了private修飾的問(wèn)題。

  • 問(wèn)題3:如果使用get方法獲取過(guò)來(lái)的是一個(gè)對(duì)象,那么我們可以通過(guò)判斷是不是Object類(lèi)來(lái)判斷是不是需要迭代處理,后來(lái)發(fā)現(xiàn),在使用一些基礎(chǔ)數(shù)據(jù)類(lèi)的時(shí)候,比如int,char,float等,他會(huì)自定的裝箱,從而導(dǎo)致我們無(wú)法處理,后來(lái)取了一個(gè)折中的辦法自定義了一個(gè)注解,在返回值是POJO對(duì)象的地方標(biāo)注,在使用反射獲取get方法中獲取這個(gè)注解,如果注解是null說(shuō)明不是POJO,如果不是null,那么我們進(jìn)行二次的迭代處理該對(duì)象,注解代碼如下:

//作用于方法上,運(yùn)行時(shí)保留
@Target(value={METHOD})
@Retention(RetentionPolicy.RUNTIME)
public  @interface NeedIterative {
    //參數(shù)沒(méi)有作用
    String value() default "";
}

詳細(xì)代碼

首先實(shí)現(xiàn)POJO類(lèi),POJO類(lèi)主要代碼如下所示<span style="color:red;">set方法已省略,自行補(bǔ)充,People類(lèi)也是</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;}

    //此處添加了注解,說(shuō)明此處返回的是一個(gè)POJO需要迭代處理
    @NeedIterative
    public People getPeople() { return new People("李亞偉",12); }

需要返回的對(duì)象POJO對(duì)象是People類(lèi)的代碼內(nèi)容為

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; }
}

反射返回對(duì)象

代碼很見(jiàn)到,都是Class等常見(jiàn)的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();
            //執(zhí)行g(shù)et方法返回一個(gè)Object
            Object exeValue = getMethod.invoke(obj);
            String key = dealMethodName(getMethod.getName());
            NeedIterative annotation = getMethod.getAnnotation(NeedIterative.class);
             //獲取的注解不為空,那么說(shuō)明此處返回的結(jié)果是對(duì)象,那么需要迭代處理
            if (annotation != null) {
                exeValue = toMap(exeValue);
            }
            hashMap.put(key, exeValue);
        }
        return hashMap;
    }

輸出結(jié)果

由此可見(jiàn),不管是基本數(shù)據(jù)類(lèi)型,還是POJO類(lèi)都能正常的轉(zhuǎn)換。

斷點(diǎn)數(shù)據(jù)類(lèi)型查看:

image

sout輸出效果如下:

{
        allow=true, 
        sex=m,
        name=周濤,
        weight=12.23,
        people={
                people=李亞偉, 
                work=12
                },
        age=23,
        height=12.12
}

更多關(guān)于Java方面的文章,歡迎訪(fǎng)問(wèn)燕歸來(lái)https://www.zhoutao123.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,609評(píng)論 19 139
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 12,441評(píng)論 6 13
  • 1.歷史作業(yè)本 2.歷史小感想 3.生物世紀(jì)金榜 簡(jiǎn)書(shū)里的以過(guò)來(lái)人的方式告訴我了一些道理 …很驚訝…很感動(dòng)…謝謝你...
    OngZiyang閱讀 311評(píng)論 0 0
  • 掩耳情話(huà),就是一個(gè)人唱完所有的對(duì)白。 金色陽(yáng)光,地平線(xiàn),海鷗 閉著眼,都能觸摸到幸福。 攜手路過(guò)玫瑰花叢,離開(kāi)時(shí),...
    輕文藝Milo閱讀 270評(píng)論 0 0
  • 前幾天我有個(gè)做技術(shù)的朋友,把自己的微信好友從2700多減少到175個(gè)。他老婆聽(tīng)說(shuō)了他把 BAT 的幾百人全都刪除了...
    正記錄Beta閱讀 525評(píng)論 12 30

友情鏈接更多精彩內(nèi)容