Gson教程十二(譯):Float和Double類型的特殊值

該文章翻譯自Gson Tutorial Series系列教程。該篇主要闡述了Gson如何處理Float和Double類型的特殊值。

上一篇博客中,我們探討了如何使得JSON的轉換具有仁慈性。仁慈性意味著允許JSON某些地方不遵循標準而Gson依然能夠解析。在這篇博客中,我們將探究一種允許非標準輸入的情況:Gson如何處理Float和Double類型的特殊值(比如**Float.NEGATIVE_INFINITY)。

Float和Double類型的特殊值

在Java中,某些特殊情況下需要將值置為float型和double型。因此,在Java語言剛開始的時候,Float.NEGATIVE_INFINITY,Float.POSITIIVE_INFINITY以及Float.NaN以及他們對應的double型就以及存在了。遺憾的是,JSON標準不知道它們的價值,并沒有將它們作為標準的一部分。

讓我們引用Gson文檔中關于該問題的描述:

JSON規范的2.4章節不允許擁有特殊的double值(NaN,Infinity,-Infinity)。然而,Javascript標準(查看章節4.3.20,4.3.22,4.3.23)允許它們作為Javascript的合法值。甚至,大部分的JavaScript引擎接收這些在JSON中的特殊值而不會發生任何問題。因此,從實踐層面來看,即使JSON規范不支持它們,但接收這些值作為合法的JSON也是有理可尋的。

記得嗎?在上一篇仁慈性的博客中我們寫道,反序列化時Gson對于JSON標準具有很棒的靈活性,而在序列化時又是靈活的。前一部分依然是正確的,但是,這些特殊的float和double值是唯一的意外,它們使得Gson會內在的違反標準。

讓我們講得再透徹一點:如果你傳入的JSON使用了一個或多個那樣的float或double邊緣值,它們會被默認反序列化,而不會有任何問題。

如果你傳遞一個Float.POSITIVE_INFINITY作為值,Gson將會拋出異常,因為Gson不能根據標準來進行轉換。如果你需要傳遞這些特殊值,你需要使用GsonBuilder來明確的指定這些值可以轉換。Gson為你提供了serializeSpecialFloatingPointValues來處理。

是時候來看一個例子了。我們來創建一個用戶類,它擁有一個float類型的成員變量weight。

public class UserFloat {  
    String name;
    Float weight;

    public UserFloat(String name, Float weight) {
        this.name = name;
        this.weight = weight;
    }
}

現在,復活節的巧克力兔女郎對我產生了負面影響,最后我的體重大增,因此我需要像下面那樣創建我的用戶實例:

UserFloat user = new UserFloat("Norman", Float.POSITIVE_INFINITY);

如果你將之傳遞給Gson,它將會拋出異常:

Gson gson = new Gson();

UserFloat user = new UserFloat("Norman", Float.POSITIVE_INFINITY);

String usersJson = gson.toJson(user); // will throw an exception  

Gson將會給你一個IllegalArgumentException異常,它的陳述如下:

Infinity并不是JSON規范的有效double值。想要使用該行為,使用serializeSpecialFloatingPointValues()方法。

異常信息是非常有幫助的,并且已經提供給了我們解決辦法。我們需要使用GsonBuilder

Float.POSITIVE_INFINITY

這將不會有任何異常,并且usersJson的內容是正確的:

GsonBuilder

當然了,這并不是100%的標準,因此你需要確認你的API是否能夠處理這些不尋常的值。

前瞻

本篇文章,你學會了Gson是如何處理費標準的JSON float值。默認情況下,Gson不允許序列化這些邊緣值。然而,你可以使用GsonBuilder來激活。

下一篇文章,我們將會探討為你的模型版本化。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容