javabean初始化賦默認值-反射實現一鍵賦值所有的字段


摘要

對接的同學提供一個jar過來,然后里面的bean是4級嵌套,然后也沒有個文檔。看着這么多的屬性心里有點蒙。看慣了swaggger的文檔格式,心里在想,有沒有一個方式可以實現這個需求。網上找了沒有,然后自己動手了。

關鍵字

反射一鍵初始化bean、序列化保留多級null

1、問題背景

​ 對接的同學提供一個jar過來,然后里面的bean是4級嵌套,也沒有個文檔。看着這么多的屬性心里有點蒙。看慣了swaggger的文檔格式,心里在想,有沒有一個方式可以實現這個需求

2、問題本質

  • 把一個bean的結構用json的方式展示出來

3、難點

  • bean的結構是多級的
  • bean中包含自定義類
  • bean中包含靜態類、內部類

4、可能的實現方式

4.1、利用三方序列化工具,比如Gson實現

XXXTaskAddInput  xxxTaskAddInput=new XXXTaskAddInput();
Gson gson=new GsonBuilder().serializeNulls().create();
System.out.println(gson.toJson(xxxTaskAddInput));

結果

{
    "groupId": null, 
    "groupName": null, 
    "tasks": null
}

從結果明顯可以看出,只是保留了一級的null屬性。所以說Gson的serializeNulls這個功能是不滿足我的這個需求的。

4.2、專注到初始化話

不難看出問題的本質不是序列化,而在於bean的初始化。因為一級屬性都是null。二級屬性自然是無法序列化出來的。所以我們的核心是實現變量bean,給所有層級的屬性賦值對應類型的默認值就好了。

簡單的查了下百度,沒有直接可用的,然后就自己動手了。反射是解決這個問題的關鍵。

5、可復用的工具類

public static void setFeidValueNotNull(Object obj) throws Exception {
        for (Field field : obj.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            if (field.get(obj) == null || field.get(obj).toString().equals("[]")) {
                if (field.getGenericType().toString().equals("class java.lang.String")) {
                    field.set(obj, "");
                } else if (field.getGenericType().toString().equals("class java.lang.Integer")) {
                    field.set(obj, 0);
                } else if (field.getGenericType().toString().equals("class java.lang.Double")) {
                    field.set(obj, 0.0);
                } else if (field.getGenericType().toString().equals("class java.lang.Long")) {
                    field.set(obj, 0L);
                } else {
                    Type type = field.getGenericType();
                    if (List.class.isAssignableFrom(field.getType())) {
                        List arraylist = new ArrayList();
                        // 這樣判斷type 是不是參數化類型。 如Collection<String>就是一個參數化類型。
                        if (type instanceof ParameterizedType) {
                            // 獲取類型的類型參數類型。  你可以去查看jdk幫助文檔對ParameterizedType的解釋。
                            Class clazz =
                                    (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
                            Object subObject = clazz.newInstance();
                            setFeidValueNotNull(subObject);
                            arraylist.add(subObject);
                        }
                        field.set(obj, arraylist);
                    } else {
                        Class clazz = Class.forName(field.getGenericType().getTypeName());
                        Object subObject = clazz.newInstance();
                        setFeidValueNotNull(subObject);
                        field.set(obj, subObject);
                    }
                }
            }
        }
    }

如何使用

XXXTaskAddInput  xxxTaskAddInput=new XXXTaskAddInput();
setFeidValueNotNull(xxxTaskAddInput);
System.out.println(new Gson().toJson(xxxTaskAddInput));

效果

{
    "groupId": "", 
    "groupName": "", 
    "tasks": [
        {
            "bizId": "", 
            "bizInfo": {
                "receiver": "", 
                "extendInfo": "", 
                "organizationId": "", 
                "exportInfos": [
                    {
                        "columnIndex": 0, 
                        "rowspan": 1, 
                        "columnName": "", 
                        "columnValue": ""
                    }
                ], 
                "result": ""
            }, 
            "name": "", 
            "type": 0, 
            "total": 0, 
            "accountOid": "", 
            "accountGid": "", 
            "receiver": ""
        }
    ]
}

是不是沒有想象中復雜,補充一句,swagger中是借助於注解實現的。

6、總結

發現問題,解決問題,總結問題。一步一個腳印的往前走。回頭看,其實所謂的困難也沒那么難。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM