1. 引言
Gson 庫,由 Google 開發,對於 Java 對象到 JSON 格式的序列化和反序列化來説是一個不錯的選擇。此外,我們通常會遇到 Gson 將整數序列化為浮點數的問題。
在本教程中,我們將探討為什麼整數會被視為浮點數。 此外,我們還將提供一種解決方案,以防止 Gson 執行此操作。
2. 問題定義
Gson 將 Java 對象序列化為 JSON。 默認情況下,Gson 將整數序列化為浮點數,以提供更準確的表示。 下面是一個簡單的示例:
public String jsonString= "[{\"id\":4077395,\"field_id\":242566,\"body\":\"\"}, " +
"{\"id\":4077398,\"field_id\":242569,\"body\":[[273019,0],[273020,1],[273021,0]]}, " +
"{\"id\":4077399,\"field_id\":242570,\"body\":[[273022,0],[273023,1],[273024,0]]}]";這裏,我們聲明瞭一個名為 jsonString 的 JSON 字符串,它代表一個對象數組。這個 JSON 數組包含不同的字段,例如 id, field_id 和 body。
現在,我們將使用 Gson 庫將 JSON 字符串反序列化為 Hashtable<String, Object> 對象的列表。
ArrayList<Hashtable<String, Object>> responses;
Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType();
responses = new Gson().fromJson(jsonString, ResponseList);
這裏,我們聲明瞭一個名為 responses 的 ArrayList,用於存儲類型為 Hashtable 的元素,這些元素具有 String 鍵和 Object 值。 此外,我們使用 Gson 庫將 jsonString 反序列化為 Hashtables 的列表。
最後,我們使用 TypeToken 在反序列化過程中獲取泛型類型信息。
responses 將格式如下:
[{
body = ,
field_id = 242566.0,
id = 4077395.0
}, {
body = [
[273019.0, 0.0],
[273020.0, 1.0],
[273021.0, 0.0]
],
field_id = 242569.0,
id = 4077398.0
}, {
body = [
[273022.0, 0.0],
[273023.0, 1.0],
[273024.0, 0.0]
],
field_id = 242570.0,
id = 4077399.0
}]請注意,Gson 將整數表示為浮點數。
3. Gson 中默認數字策略
Gson 的默認數字策略旨在在表示數值時,兼顧準確性和靈活性。 Gson 採用浮點數表示整數的做法,基於 JSON 缺乏區分整數和浮點數類型的明確支持這一事實。 因此,Gson 默認採用一種策略,以確保數值的精度得以保留。
然而,這種默認行為可能與特定要求或偏好不一致,尤其是在 JSON 表示中,整數應保持整數的情況下。
4. 使用 setObjectToNumberStrategy() 方法
使用 Gson 方法 setObjectToNumberStrategy(),我們可以充分控制對象轉數字轉換機制在反序列化過程中的功能。
讓我們通過一個示例來探索這種能力:
public static String expectedOutput ="[{body=, field_id=242566, id=4077395}, " +
"{body=[[273019, 0], [273020, 1], [273021, 0]], field_id=242569, id=4077398}, " +
"{body=[[273022, 0], [273023, 1], [273024, 0]], field_id=242570, id=4077399}]";
@Test
public void givenJsonString_whenUsingsetObjectToNumberStrategyMethod_thenValidateOutput() {
Gson gson = new GsonBuilder()
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.create();
ArrayList<Hashtable<String, Object>> responses = gson.fromJson(jsonString,
new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType());
assertEquals(expectedOutput, responses.toString());
}在此,使用 setObjectToNumberStrategy() 方法使我們能夠設置策略,例如 ToNumberPolicy.LONG_OR_DOUBLE,以便Gson根據數值值對其行為進行定向。最後,我們使用 assertEquals() 方法驗證轉換過程。
此外,Gson 中的 ToNumberPolicy 枚舉支持多種策略,用於處理數值值。除了我們在示例中使用的 ToNumberPolicy.LONG_OR_DOUBLE,其他策略包括:
- ToNumberPolicy.DOUBLE_ONLY: 在反序列化過程中將所有數值值轉換為 double
- ToNumberPolicy.LONG_ONLY: > 在反序列化過程中將所有數值值轉換為 long
- ToNumberPolicy.DEFAULT: > 保留Gson的默認行為,將整數表示為浮點數
5. 結論
在本文中,我們討論了 Gson 中遇到的一個問題:整數在序列化過程中會被自動轉換為浮點數。為了解決這個問題,我們使用 <em >setObjectToNumberStrategy()</em> 方法。