此部落格為部落客原創文章,轉載請标明出處,維權必究:https://www.cnblogs.com/tangZH/p/10689536.html
更多精彩文章:http://77blogs.com/?p=301
fastjson是很好用的json解析工具,隻可惜項目中要求apk體積盡量小,是以并不打算引入fastJson,隻好自己寫一個,遺憾的是寫出的這個并沒法解析所有的json資料,不過還是很值得學習的,且聽我一一道來。
主要實作兩個功能:
1、将jsonArray解析為List
2、将json資料轉化為class
當然,class裡面的成員變量的名稱需要與json裡面的key一樣。
思路:
1、通過反射擷取class類裡面的成員變量名稱以及類型
2、通過成員變量的名稱與類型去json資料中擷取該key對應的value
2、将value通過反射指派給class對象。
具體且看:
1、定義一個實體類儲存class裡面的反射擷取到的每個成員變量對應字段,名稱,類型
static class ValueHelper {
String name;
String type;
Field field;
}
2、将json資料轉換為實體類
public static <T> T parseJson2Obj(String data, Class<T> tClass) {
if (TextUtils.isEmpty(data))
return null;
try {
List<ValueHelper> listKey;
//獲得自己的所有屬性
Field[] fields = tClass.getFields();
if (null == fields)
return null;
listKey = new ArrayList<>();
for (Field field : fields) {
ValueHelper helper = new ValueHelper();
helper.name = field.getName();
helper.type = field.getGenericType().toString();
helper.field = field;
listKey.add(helper);
}
//将所有的屬性儲存在keyList集合中
//執行個體化給實體類,以便對其進行反射指派
Object c = tClass.newInstance();
JSONObject object = new JSONObject(data);
for (int j = 0; j < listKey.size(); j++) {
ValueHelper helper = listKey.get(j);
//取出實體類中的屬性,根據名稱與類型去jsonObject中取值,
//具體實作接下來會講
Object o = getJsonValue(helper, object);
//指派給該實體類,具體實作記下來會講
setProperty(c, helper.field, o);
}
//傳回該實體類
return (T) c;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
2.1 取出實體類中的屬性,根據名稱與類型去jsonObject中取值
public static Object getJsonValue(ValueHelper helper, JSONObject object) throws JSONException {
switch (helper.type) {
case "class java.lang.String":
return object.optString(helper.name, "");
case "class java.lang.Integer":
case "int":
return object.optInt(helper.name, 0);
case "class java.lang.Double":
return object.optDouble(helper.name, 0);
case "class java.lang.Boolean":
return object.optBoolean(helper.name, false);
}
//如果該成員變量是泛型
if (helper.field.getGenericType() instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) helper.field.getGenericType();
//判斷具體類的類型,list集合或者ArrayList
if (pt.getRawType().equals(List.class) || pt.getRawType().equals(ArrayList.class)) {
//那麼它對應在json中的是一個jsonArray
JSONArray array = object.getJSONArray(helper.name);
//如果集合裡面的泛型為String
if (pt.getActualTypeArguments()[0].equals(String.class)) {
//将該jsonArray轉化為list,具體實作接下來會講,
//其實就相當于多次執行json轉化為class,然後放入list中
//如果泛型參數為class實體類,那我就不知道該怎麼解析了,
//不知道怎麼判斷裡面的泛型參數是否為實體類
//這也是我所說的沒法解析所有的json資料
List<String> sList = JsonArrayToList(array);
return sList;
}
}
}
return null;
}
2.2 給實體類指派
public static void setProperty(Object c, Field field, Object value)
throws SecurityException,
IllegalArgumentException, IllegalAccessException {
if (null == c || null == value)
return;
// 取消通路檢查(私有成員變量的時候需要)
field.setAccessible(true);
// 給對象的成員變量指派為指定的值--->value
field.set(c, value);
}
2.3 JsonArrayToList方法
public static <T> List<T> JsonArrayToList(JSONArray ja) {
List<T> ret = new ArrayList();
if (ja == null) {
return ret;
} else {
for(int i = 0; i < ja.length(); ++i) {
try {
Object obj = ja.get(i);
if (obj != null) {
ret.add(obj);
}
} catch (JSONException var4) {
;
}
}
return ret;
}
}
3、将jsonArray轉為list<class>,注意參數json是jsonArray資料,原理類似,就不再多講
public static <T> List<T> parseJsonArray2List(String json, Class<? extends T> aClass) {
//反射擷取所有public字段,包括父類
List<T> list = null;
List<ValueHelper> listKey;
try {
JSONArray array = new JSONArray(json);
if (null == array)
return list;
//獲得自己的所有屬性
Field[] fields = aClass.getFields();
if (null == fields)
return null;
listKey = new ArrayList<>();
for (Field field : fields) {
ValueHelper helper = new ValueHelper();
helper.name = field.getName();
helper.type = field.getGenericType().toString();
helper.field = field;
listKey.add(helper);
}
list = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
Object c = aClass.newInstance();
for (int j = 0; j < listKey.size(); j++) {
ValueHelper helper = listKey.get(j);
Object o = getJsonValue(helper, object);
setProperty(c, helper.field, o);
}
list.add((T) c);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return list;
}