1. 程式人生 > >類轉json的基類實現

類轉json的基類實現

# 類轉json的基類實現 ## 專案地址 [github地址](https://github.com/libo1223/androidStudy/blob/master/app/src/main/java/com/example/androidstudy/ToJson/Readme.md) ## 實現原理 使用反射獲取類的屬性名和屬性內容。具體原理可以自己查一下資料 對一個類呼叫getClass().getDeclaredFields()可以獲取許多資訊。 通過上述方法獲取到的是一個Field型別的陣列,這個類中有多少屬性就有多少field,包括用private修飾的屬性。 呼叫field.getName即可獲得string型別的屬性名,如下 ```java for(Field field : fields){ String name = field.getName(); } ``` 有了這個屬性名稱還不夠,還需要屬性的內容,使用field.get()方法,get中放入父類 ```java Field[] fields = this.getClass().getDeclaredFields(); //遍歷 for(Field field : fields){ Object object = field.get(this); ``` 這樣子就可以直接獲取到屬性內容,然後這裡只需要建立一個JsonObject,把屬性名和屬性內容一一填入即可,最多再加一個判斷內容是不是為null即可。 一個雛形方法就出來了,到這也可以簡單的輸出一個JsonObject的物件了。 ## 升級版 直接使用這個方法,會發現有些引數的值怎麼有點不協調,是型別加hash的形式,這樣可不太好。如果是自定義型別那也就算了,當一些基礎型別陣列形式下輸出也是這樣,那可就不太好了。不過如果是list的話卻沒有問題 先呼叫getType方法判斷下陣列傳入時的型別,然後根據這些型別,建立對應的list,將他們填入list中,將得到的list放到JsonObject中,當然也可以直接用一個JsonObject去封裝一個出來,然後放進去,但是看起來怪怪的。 如下是我自己測了一下各基本型別的type, ```java case "[Z": //boolean case "[B"://byte case "[C"://char case "[D"://double case "[F"://float case "[J"://long case "[S"://short case "[I"://int ``` 如果是大寫的基礎型別是繼承自Object的,這種比較好統一處理,type型別是由“[L”開頭,寫個if判斷下就好了。把陣列轉為list的方法如下 ```java /** * 陣列轉成list * */ private List arrayToList(Object object, @NotNull ObjectType type){ List a = new ArrayList(); switch (type){ case INT: for(int i:(int[]) object){ a.add(i); } break; case BOOLEAN: for(boolean i:(boolean[]) object){ a.add(i); } break; case LONG: for(long i:(long[]) object){ a.add(i); } break; case FLOAT: for(float i:(float[]) object){ a.add(i); } break; case DOUBLE: for(Double i:(double[]) object){ a.add(i); } break; case BYTE: for(byte i:(byte[]) object){ a.add(i); } break; case CHAR: for(char i:(char[]) object){ a.add(i); } break; case SHORT: for(short i:(short[]) object){ a.add(i); } break; case OBJECT: for(Object i:(Object[]) object){ a.add(i); } break; default: a = null; break; } return a; } ``` 我自己寫了個列舉,當他為Object時,表示是繼承自Object的型別處理起來就很方便了。直接把list型別的引數存入JsonObject中也不會出現hash值。 ## 最終版 如果屬性是一個自定義類怎麼辦呢,如果自定義類中還有一個自定義類呢。 這問題其實很簡單,如果屬性是自定義類怎麼辦,那肯定是拆他,怎麼拆,他爹怎麼被拆的就怎麼拆他。只需要遞迴就可以解決。 但是如果自定義類是陣列形式怎麼辦,之前只是列出了基礎型別的type,如果是java自己的類,肯定是java開頭的,所以只需如下判斷 ```java if(type.startsWith("java")){ return ObjectType.NOTLIST; }else if(type.startsWith("[L")){ //繼承了Object的陣列 if(type.startsWith("[Ljava")) return ObjectType.OBJECT; return ObjectType.NOTBASELIST; } ``` "[L"則是陣列型別的字首,"[Ljava"則是表示java自帶型別,所以剔除這兩個之外就是自定義類了,如果你的類的包名正好也是java開頭的,那還有個辦法,把你自己的包名填入這裡如“[Ljava.util.”,把自己篩出來。或者直接用改成“[Ljava.util.”排除所有java.util下的包也可。具體看自己操作。 這個專案的實現使用android實現的,如果是java的話就自己寫寫實現看看效果。具體使用可以詳見github裡的readme