1. 程式人生 > 其它 >javabean初始化賦預設值-反射實現一鍵賦值所有的欄位

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、總結

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

.