防止 Gson 將整數表示為浮點數
一、簡介
Google 開發的 Gson 函式庫對於 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);
在這裡,我們宣告一個名為response的ArrayList
,其中包含帶有String
鍵和Object
值的Hashtable
類型的元素。此外,我們利用 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 預設的數字策略旨在在表示數值時在準確性和靈活性之間取得平衡。使用浮點數表示整數的決定是基於 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()
方法使我們能夠為 Gson 設定一個策略,例如ToNumberPolicy.LONG_OR_DOUBLE
來指導其關於數值的行為。最後,我們使用assertEquals()
方法來驗證轉換過程。
此外,Gson 中的ToNumberPolicy
枚舉支援各種處理數值的策略。除了我們在範例中使用的ToNumberPolicy.LONG_OR_DOUBLE
之外,其他策略還包括:
-
**ToNumberPolicy.DOUBLE_ONLY:**
反序列化期間將所有數值轉換為 double - **
ToNumberPolicy.LONG_ONLY:
**反序列化期間將所有數值轉換為 long - **
ToNumberPolicy.DEFAULT:
**保留Gson的預設行為,將整數表示為浮點數
5. 結論
在本文中,我們討論 Gson 遇到的一個問題:整數在序列化過程中會自動轉換為浮點數。為了解決這個問題,我們使用setObjectToNumberStrategy()
方法。
與往常一樣,本文的完整程式碼範例可以在 GitHub 上找到。