在上一篇文章中,我們重點探討了如何使用 json-lib 實現 JSON 字符串與 Java 對象的相互轉換。然而,json-lib 內部兩個極其關鍵的核心類——JSONObject 和 JSONArray——卻常被忽視。這兩個類分別對應 JSON 中的對象格式({})和數組格式([]),掌握它們的底層原理與靈活用法,能讓你在處理複雜 JSON 結構時遊刃有餘。本文將結合源碼分析與實戰代碼,帶你徹底搞懂這兩大核心類。
翻閱 JSONObject 源碼,會發現它內部持有一個 Map 類型的屬性 properties,且在無參構造器中被初始化為 ListOrderedMap(保證插入順序):
private Map properties;
/** Construct an empty JSONObject. */
public JSONObject() {
this.properties = new ListOrderedMap();
}
所有的 element() 方法本質上都是向這個 properties Map 中存入鍵值對;同理,get() 系列方法直接委託給 Map 的 get(key)。換句話說,操作 JSONObject 就是在操作一個有序的 Map。
public static void testJSONObject() {
JSONObject jsonObject = new JSONObject();
jsonObject.element("my", "this is my first");
String str = jsonObject.toString(); // {"my":"this is my first"}
String keyValue = jsonObject.getString("my"); // this is my first
System.out.println("str: " + str);
System.out.println("keyValue: " + keyValue);
}
可以將 "my" 視為類屬性,"this is my first" 為屬性值,這與將 Java Bean 序列化為 JSON 字符串的效果一致。
無需定義對應的 Java Bean,直接用 JSONObject.fromObject(str) 解析字符串,再用 getString()、getJSONObject() 等方法按需提取:
String str = "{\"my\":\"this is my first\",\"second\":\"this is second!\"}";
JSONObject jsonObject = JSONObject.fromObject(str);
String my = jsonObject.getString("my");
String second = jsonObject.getString("second");
面對 {"data":{"my":"...","second":"..."}} 這類嵌套對象,關鍵在於使用 getJSONObject("data") 獲取內層 JSONObject,而非 getString()(後者只返回字符串,難以進一步解析):
String str = "{\"data\":{\"my\":\"this is my first\",\"second\":\"this is second!\"}}";
JSONObject jsonObject = JSONObject.fromObject(str);
JSONObject dataObject = jsonObject.getJSONObject("data"); // 關鍵步驟
System.out.println(dataObject.toString()); // {"my":"this is my first","second":"this is second!"}
若業務確實需要強類型對象,可調用 toBean(jsonObject, TargetClass.class),前提是目標類擁有對應的屬性與 Getter/Setter。
/** The List where the JSONArray's properties are kept. */
private List elements;
/** Construct an empty JSONArray. */
public JSONArray() {
this.elements = new ArrayList();
}
所有元素按順序存放在 elements 中,因此 JSONArray 的操作本質是基於數組/列表的下標訪問。
public static void testJSONArray() {
String array = "[\"123\",\"this is my test\",{\"address\":\"北京市朝陽區\",\"age\":\"23\",\"name\":\"JSON\"}]";
JSONArray jsonArray = JSONArray.fromObject(array);
// 簡單類型直接按下標取字符串
String str1 = jsonArray.getString(0); // 123
String str2 = jsonArray.getString(1); // this is my test
String str3 = jsonArray.getString(2); // {"address":"北京市朝陽區","age":"23","name":"JSON"}
// 第三個元素是對象,需用 getJSONObject 進一步解析
JSONObject obj = jsonArray.getJSONObject(2);
String address = obj.getString("address"); // 北京市朝陽區
String age = obj.getString("age"); // 23
}
輸出結果:
str1:123,str2:this is my test,str3:{"address":"北京市朝陽區","age":"23","name":"JSON"}
address:北京市朝陽區,age:23
getJSONObject(key) / getJSONObject(index) 逐層剝離,避免用 getString() 產生難以解析的字符串;掌握這兩大核心類的本質與用法,能讓你在面對各種複雜 JSON 場景時,從容應對,寫出更簡潔高效的代碼。