Gson用戶指南

概況

Gson是一個Java庫炼杖,它可以用來把Java對象轉(zhuǎn)換為JSON表達式蜗字,也可以反過來把JSON字符串轉(zhuǎn)換成與之相同的Java對象
Gson可以對任何Java對象使用包括那些你沒有源碼的對象,但已存在的對象

Gson的目標

  • 提供簡單易用的機制類似于toString()和構(gòu)造器(工廠模式)用來進行Java和JSON互相轉(zhuǎn)換
  • 允許把預(yù)先存在但無法修改的對象轉(zhuǎn)換為JSON或從JSON轉(zhuǎn)換
  • 允許對象的自定義表示
  • 支持任何復(fù)雜的對象
  • 生成緊湊易讀的JSON輸出

Gson的性能和可延展性

這里提供的一些參數(shù)是從我們的一臺筆記本(雙核AMD皓龍?zhí)幚砥鳎?GB RAM娩缰,64位Ubuntu系統(tǒng))上運行了很多的測試用例中獲取的蓬痒,你也可以用PerformanceTest類來重新運行這些測試案例

  • 對于字符串:反序列化超過25MB的字符串沒有任何問題(可以查看PerformanceTest下的方法disabled_testStringDeserializationPerformance)

  • 對于大型集合:

    • 序列化過一個擁有1400萬個對象的集合(可以查看PerformanceTest下的disabled_testLargeCollectionSerialization方法)
      -反序列化過一個擁有8.7萬個對象的集合(可以查看PerformanceTest下的disabled_testLargeCollectionDeserialization方法)
      -Gson的1.4版本將字節(jié)數(shù)組和集合的反序列化最大值從80KB提高到了11MB

提示:運行這些測試用例時要刪除disabled_前綴,我們使用這些前綴是為了在每次運行JUnit測試時避免運行到上述例子

Gson的用戶

Gson原本是創(chuàng)造給Google內(nèi)部人員使用并運用在目前的的很多Google項目中∑岣幔現(xiàn)在被很多公共項目和公司所使用

使用Gson

Gson的主要用到的類是Gson,你可以直接通過調(diào)用new Gson()來生成狱掂,也可以用類GsonBuilder來創(chuàng)建Gson實例演痒,這樣創(chuàng)建就可以自主進行參數(shù)設(shè)置類似于版本控制之類

Gson實例不會保留任何狀態(tài)當你調(diào)用Json操作時,所以你可以隨意的重用一個對象操作多個Json序列化和反序列化操作

Android:在Gradle上使用Gson

dependencies {
    implementation 'com.google.code.gson:gson:2.8.5'
}

在Maven上使用Gson

要在Maven2/3中使用Gson趋惨,你可以在Maven庫中找到Gson合適的版本添加到下面的dependency

<dependencies>
    <!--  Gson: Java to Json conversion -->
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.8.5</version>
      <scope>compile</scope>
    </dependency>
</dependencies>

這樣你的maven項目就可以用Gson了

基本例子

// 序列化
Gson gson = new Gson();
gson.toJson(1);            // ==> 1
gson.toJson("abcd");       // ==> "abcd"
gson.toJson(new Long(10)); // ==> 10
int[] values = { 1 };
gson.toJson(values);       // ==> [1]

// 反序列化
int one = gson.fromJson("1", int.class);
Integer one = gson.fromJson("1", Integer.class);
Long one = gson.fromJson("1", Long.class);
Boolean false = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"abc\"", String.class);
String[] anotherStr = gson.fromJson("[\"abc\"]", String[].class);

關(guān)于對象的例子

class BagOfPrimitives {
  private int value1 = 1;
  private String value2 = "abc";
  private transient int value3 = 3;
  BagOfPrimitives() {
    // no-args constructor
  }
}

// 序列化
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);  

// ==> json is {"value1":1,"value2":"abc"}

注意你不能序列化有循環(huán)調(diào)用的對象鸟顺,不然會返回一個無限遞歸的結(jié)果

// 反序列化
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
// ==> obj2 is just like obj
對象的細節(jié)
  • 對象里使用private是完全可以運行的,而且我們推薦你這么做
  • 不用聲明什么區(qū)域需要被序列化或者反序列化器虾,當前類的所有區(qū)域(包括所有的超類)都被默認包括進去
  • 如果字段被標記為瞬態(tài)讯嫂,(默認情況下)會被忽略不會被包括在JSON序列化或者反序列化中
  • 這實現(xiàn)這么處理的Null值(?)
    • 序列化時兆沙,輸出中省略了空字段欧芽。
    • 當反序列化時,當類中的區(qū)域在JSON結(jié)果中找不到時默認會設(shè)置:對象會設(shè)置為null葛圃,數(shù)字類型會設(shè)置為0千扔,布爾類型會設(shè)置為false
  • 如果類型是syntactic,會被忽略库正,不被包含在JSON序列化或反序列化
  • 與內(nèi)部類曲楚,匿名類和本地類中的外部類對應(yīng)的字段將被忽略,并且不包括在序列化或反序列化中褥符。
嵌套類(包含內(nèi)部類)

Gson可以簡單的序列化靜態(tài)嵌套類

Gson 還可以反序列化靜態(tài)嵌套類龙誊。但是,Gson 不能自動反序列化純內(nèi)部類喷楣,因為它們的 no-args 構(gòu)造函數(shù)還需要對反序列化時不可用的包含 Object 的引用趟大。您可以通過使內(nèi)部類靜態(tài)或為其提供自定義 InstanceCreator 來解決此問題
這是一個例子:

public class A { 
  public String a; 

  class B { 

    public String b; 

    public B() {
      // No args constructor for B
    }
  } 
}

注意:上述 B 類不能(默認情況下)使用 Gson 序列化。

{"b":"abc"}由于 B 類是一個內(nèi)部類抡蛙,Gson 不能反序列化為 B 的實例护昧。如果它被定義為靜態(tài)類 B,那么 Gson 就能夠反序列化字符串粗截。另一種解決方案是為 B 編寫自定義實例創(chuàng)建器惋耙。

public class InstanceCreatorForB implements InstanceCreator<A.B> {
  private final A a;
  public InstanceCreatorForB(A a)  {
    this.a = a;
  }
  public A.B createInstance(Type type) {
    return a.new B();
  }
}

上述代碼可以運行但是不推薦

數(shù)組例子
Gson gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};

// Serialization
gson.toJson(ints);     // ==> [1,2,3,4,5]
gson.toJson(strings);  // ==> ["abc", "def", "ghi"]

// Deserialization
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class); 
// ==> ints2 will be same as ints

我們也支持多尺寸數(shù)組和任何復(fù)雜的元素類型

集合例子
Gson gson = new Gson();
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);

// Serialization
String json = gson.toJson(ints);  // ==> json is [1,2,3,4,5]

// Deserialization
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);
// ==> ints2 is same as int

可怕的現(xiàn)象:注意到我們怎么定義collection類型的嗎?不幸的是,在Java里不能這么做

集合的限制
Gson可以序列化任意形式的集合但是不能把它反序列绽榛,因為沒法給用戶表明結(jié)果對象(湿酸?),反而灭美,當反序列化時推溃,集合必須是具體和通用的類型,大家都知道届腐,當遵循良好的編碼習(xí)慣就很少出現(xiàn)問題

當序列化和反序列化泛型

當你調(diào)用toJson(obj)铁坎,Gson會調(diào)用obj.getClass()來獲取區(qū)域的信息去序列化,同樣犁苏,你可以通過MyClass.class對象的fromJson(json, MyClass.class)方法.如果對象里沒有泛型這么做也可以硬萍。但是,如果你的對象里有泛型围详,這么做泛型會丟失朴乖,因為Java的類型擦除,這有個例子來說明這點

class Foo<T> {
  T value;
}
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); // May not serialize foo.value correctly

gson.fromJson(json, foo.getClass()); // Fails to deserialize foo.value as Bar

上述代碼想賦予value的類型Bar但失敗了因為Gson調(diào)用了list.getClass()方法去獲取這個類的信息助赞,但是返回一個純類Foo.class买羞。這就是說Gson沒有方法知道你的對象的類型是Foo<Bar>而不是Foo

你可以通過確定正確的參數(shù)來代替泛型可以解決上述問題雹食,你也可以用TypeToken

Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);

gson.fromJson(json, fooType);

慣用方法是獲取fooType來實際定義一個匿名內(nèi)部類來包含用來返回整個參數(shù)類型的getType()方法

序列化和反序列化帶有任意類型對象的集合

有時候你需要處理帶有雜亂類型的JSON數(shù)組畜普,像是['hello',5,{name:'GREETINGS',source:'guest'}]
與之相等的Collection包含:

Collection collection = new ArrayList();
collection.add("hello");
collection.add(5);
collection.add(new Event("GREETINGS", "guest"));

Event定義成:

class Event {
  private String name;
  private String source;
  private Event(String name, String source) {
    this.name = name;
    this.source = source;
  }
}

你可以直接用Gson去序列化集合而且不用做其他任何事情,toJson(collection)會寫出你期待的輸出

但是婉徘,反序列化fromJson(json, Collection.class)無法工作漠嵌,因為 Gson 無法知道如何將輸入映射到類型。Gson 要求您提供集合類型的通用版本fromJson()盖呼。所以儒鹿,你有三個選擇:

  1. 使用 Gson 的解析器 API(低級流解析器或 DOM 解析器 JsonParser)來解析數(shù)組元素,然后Gson.fromJson()在每個數(shù)組元素上使用几晤。這是首選方法约炎。這是一個演示如何執(zhí)行此操作的示例

  2. 注冊一個類型適配器Collection.class,查看每個數(shù)組成員并將它們映射到適當?shù)膶ο笮否_@種方法的缺點是它會搞砸 Gson 中其他集合類型的反序列化圾浅。

  3. 注冊一個類型的適配器MyCollectionMemberType,并使用fromJson()Collection<MyCollectionMemberType>憾朴。

僅當數(shù)組顯示為頂級元素或者您可以更改將集合保持為類型的字段類型時狸捕,此方法才可用Collection<MyCollectionMemberType>众雷。

內(nèi)置的序列化器和反序列化器

Gson 有常用類的內(nèi)置序列化器和反序列化器灸拍,其默認表示可能不合適做祝。以下是此類的列表:

  1. java.net.URL 把它與字符串匹配 "https://github.com/google/gson/"
  2. java.net.URI 把它與字符串匹配 "/google/gson/"

您還可以在此頁面找到一些常用類的源代碼,例如 JodaTime 鸡岗。

自定義序列化和反序列化

有時默認表示不是您想要的混槐。處理庫類(DateTime 等)時經(jīng)常會出現(xiàn)這種情況。Gson 允許您注冊自己的自定義序列化程序和反序列化程序轩性。這是通過定義兩部分來完成的:

  • Json Serializers:需要為對象定義自定義序列化

  • Json Deserializers:需要為類型定義自定義反序列化

  • Instance Creators:如果 no-args 構(gòu)造函數(shù)可用或注冊了反序列化器声登,則不需要

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(MyType2.class, new MyTypeAdapter());
gson.registerTypeAdapter(MyType.class, new MySerializer());
gson.registerTypeAdapter(MyType.class, new MyDeserializer());
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());

registerTypeAdapter 調(diào)用檢查類型適配器是否實現(xiàn)了多個這些接口并為所有接口注冊它。

編寫序列化程序

以下是如何為 JodaTime DateTime類編寫自定義序列化程序的示例揣苏。

private class DateTimeSerializer implements JsonSerializer<DateTime> {
  public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
    return new JsonPrimitive(src.toString());
  }
}

Gson在序列化過程中遇到DateTime對象時調(diào)用serialize()悯嗓。

編寫煩序列化程序

下面是如何為JodaTime DateTime類編寫自定義反序列化器的示例。

private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
  public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new DateTime(json.getAsJsonPrimitive().getAsString());
  }
}

當需要將JSON字符串片段反序列化為DateTime對象時卸察,Gson調(diào)用deserialize

序列化器和反序列化器的細節(jié)

通常绅作,您希望為與原始類型對應(yīng)的所有泛型類型注冊單個處理程序

  • 例如,假設(shè)您有一個Id用于 id 表示 / 轉(zhuǎn)換的類(即內(nèi)部表示與外部表示)蛾派。
  • Id<T> 對所有泛型類型具有相同序列化的類型
    • 基本上寫出 id 值
  • 反序列化非常相似但不完全相同
    • 需要調(diào)用new Id(Class<T>, String)哪個返回一個實例Id<T>

Gson 支持為此注冊一個處理程序。您還可以為特定的泛型類型注冊特定的處理程序(比如Id<RequiresSpecialHandling>需要特殊處理)个少。在Type該參數(shù)toJson()fromJson()包含的通用類型的信息來幫助你編寫對應(yīng)于同一原始類型的所有泛型類型單一的處理程序洪乍。

編寫實例創(chuàng)建器

在反序列化 Object 時,Gson 需要創(chuàng)建該類的默認實例夜焦。用于序列化和反序列化的良好的類應(yīng)該具有無參數(shù)構(gòu)造函數(shù)壳澳。

  • 與用public還是private無關(guān)

通常,在處理未定義無參數(shù)構(gòu)造函數(shù)的庫類時茫经,需要實例創(chuàng)建器

實例創(chuàng)建器示例

private class MoneyInstanceCreator implements InstanceCreator<Money> {
  public Money createInstance(Type type) {
    return new Money("1000000", CurrencyCode.USD);
  }
}

類型可以是相應(yīng)的泛型類型

  • 對于調(diào)用需要特定泛型類型信息的構(gòu)造函數(shù)非常有用
  • 例如巷波,如果Id類存儲了正在為其創(chuàng)建 Id 的類

參數(shù)化類型的 InstanceCreator

有時,您嘗試實例化的類型是參數(shù)化類型卸伞。通常抹镊,這不是問題,因為實際的實例是原始類型荤傲。這是一個例子:

class MyList<T> extends ArrayList<T> {
}

class MyListInstanceCreator implements InstanceCreator<MyList<?>> {
    @SuppressWarnings("unchecked")
  public MyList<?> createInstance(Type type) {
    // No need to use a parameterized list since the actual instance will have the raw type anyway.
    return new MyList();
  }
}

但是垮耳,有時您需要根據(jù)實際參數(shù)化類型創(chuàng)建實例。在這種情況下遂黍,您可以使用傳遞給createInstance方法的 type 參數(shù)终佛。這是一個例子:

public class Id<T> {
  private final Class<T> classOfId;
  private final long value;
  public Id(Class<T> classOfId, long value) {
    this.classOfId = classOfId;
    this.value = value;
  }
}

class IdInstanceCreator implements InstanceCreator<Id<?>> {
  public Id<?> createInstance(Type type) {
    Type[] typeParameters = ((ParameterizedType)type).getActualTypeArguments();
    Type idType = typeParameters[0]; // Id has only one parameterized type T
    return Id.get((Class)idType, 0L);
  }
}

在上面的示例中,如果沒有實際傳入?yún)?shù)化類型的實際類型雾家,則無法創(chuàng)建 Id 類的實例铃彰。我們通過使用傳遞的方法參數(shù)來解決這個問題typetype在這種情況下芯咧,對象是 Java 參數(shù)化類型表示Id<Foo>實際實例應(yīng)綁定到的位置Id<Foo>牙捉。由于Idclass 只有一個參數(shù)化類型參數(shù)竹揍,T我們使用返回的類型數(shù)組的第 0 個元素,在這種情況下getActualTypeArgument()它將保存Foo.class鹃共。

JSON輸出形式:緊湊輸出VS優(yōu)雅輸出

Gson 提供的默認 JSON 輸出是緊湊的 JSON 格式鬼佣。這意味著輸出 JSON 結(jié)構(gòu)中不會有任何空格。因此霜浴,JSON 輸出中的字段名稱及其值晶衷,對象字段和數(shù)組內(nèi)的對象之間不會有空格。同樣阴孟,輸出中將忽略 “null” 字段(注意:null 值仍將包含在對象的集合 / 數(shù)組中)晌纫。有關(guān)配置 Gson 以輸出所有空值的信息,請參閱Null 對象支持部分永丝。

如果要使用 “優(yōu)雅輸出” 功能锹漱,則必須使用GsonBuilder來創(chuàng)建Gson實例。JsonFormatter沒有在我們的公共 API 公開慕嚷,所以用戶無法為JSON的輸出形式做配置和調(diào)整哥牍,目前,我們只提供JsonPrintFormatter默認行長度為 80 個字符喝检,2 個字符縮進和 4 個字符右邊距嗅辣。

以下是一個示例,說明如何配置Gson實例以使用默認值JsonPrintFormatter而不是JsonCompactFormatter

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);

空對象支持
在 Gson 中實現(xiàn)的默認行為null是忽略對象字段挠说。這允許更緊湊的輸出格式澡谭;但是,用戶必須為這些字段定義默認值损俭,因為 JSON 格式將轉(zhuǎn)換回其 Java 表單蛙奖。

以下是配置Gson實例輸出 null 的方法:

Gson gson = new GsonBuilder().serializeNulls().create();

注意:在使用 Gson 序列化 null 時,它會向JsonElement結(jié)構(gòu)添加JsonNull元素杆兵。因此雁仲,此對象可用于自定義序列化 / 反序列化。

這是一個例子:

public class Foo {
  private final String s;
  private final int i;

  public Foo() {
    this(null, 5);
  }

  public Foo(String s, int i) {
    this.s = s;
    this.i = i;
  }
}

Gson gson = new GsonBuilder().serializeNulls().create();
Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);

json = gson.toJson(null);
System.out.println(json);

輸出是:

{"s":null,"i":5}
null

版本控制支持

使用@Since注釋可以維護同一對象的多個版本琐脏。此批注可用于類伯顶,字段以及將來的發(fā)行版中的方法。要利用此功能骆膝,必須將Gson實例配置為忽略任何大于某個版本號的字段 / 對象祭衩。如果沒有在Gson實例上設(shè)置任何版本,則無論版本如何阅签,它都將序列化和反序列化所有字段和類掐暮。

public class VersionedClass {
  @Since(1.1) private final String newerField;
  @Since(1.0) private final String newField;
  private final String field;

  public VersionedClass() {
    this.newerField = "newer";
    this.newField = "new";
    this.field = "old";
  }
}

VersionedClass versionedObject = new VersionedClass();
Gson gson = new GsonBuilder().setVersion(1.0).create();
String jsonOutput = gson.toJson(someObject);
System.out.println(jsonOutput);
System.out.println();

gson = new Gson();
jsonOutput = gson.toJson(someObject);
System.out.println(jsonOutput);

輸出是:

{"newField":"new","field":"old"}

從序列化和反序列化中排除字段

Gson 支持許多排除頂級類,字段和字段類型的機制政钟。下面列出的是可插入的機制路克,允許字段和類排除樟结。如果以下機制都不能滿足您的需求,那么您始終可以使用自定義序列化程序和反序列化程序精算。

Java 修飾符排除

默認情況下瓢宦,如果將字段標記為transient,則將排除該字段灰羽。同樣驮履,如果某個字段被標記為static默認情況下將被排除。如果要包含一些瞬態(tài)字段廉嚼,則可以執(zhí)行以下操作:

import java.lang.reflect.Modifier;
Gson gson = new GsonBuilder()
    .excludeFieldsWithModifiers(Modifier.STATIC)
    .create();

注意:您可以為方法excludeFieldsWithModifiers提供任意數(shù)量的Modifier常量玫镐。例如:

Gson gson = new GsonBuilder()
    .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
    .create();

GSON 的 @Expose

此功能提供了一種方法,您可以將要排除的對象的某些字段標記為序列化和反序列化為 JSON怠噪。要使用此批注恐似,必須使用創(chuàng)建 Gson new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()。創(chuàng)建的 Gson 實例將排除類中未標注@Expose注釋的所有字段傍念。

用戶定義的排除策略

如果排除字段和類類型的上述機制對您不起作用矫夷,那么您始終可以編寫自己的排除策略并將其插入 Gson。有關(guān)ExclusionStrategy更多信息憋槐,請參閱 JavaDoc口四。

以下示例顯示如何排除標記有特定@Foo注釋的字段,并排除類的頂級類型(或聲明的字段類型)String秦陋。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Foo {
  // Field tag only annotation
}

public class SampleObjectForTest {
  @Foo private final int annotatedField;
  private final String stringField;
  private final long longField;
  private final Class<?> clazzField;

  public SampleObjectForTest() {
    annotatedField = 5;
    stringField = "someDefaultValue";
    longField = 1234;
  }
}

public class MyExclusionStrategy implements ExclusionStrategy {
  private final Class<?> typeToSkip;

  private MyExclusionStrategy(Class<?> typeToSkip) {
    this.typeToSkip = typeToSkip;
  }

  public boolean shouldSkipClass(Class<?> clazz) {
    return (clazz == typeToSkip);
  }

  public boolean shouldSkipField(FieldAttributes f) {
    return f.getAnnotation(Foo.class) != null;
  }
}

public static void main(String[] args) {
  Gson gson = new GsonBuilder()
      .setExclusionStrategies(new MyExclusionStrategy(String.class))
      .serializeNulls()
      .create();
  SampleObjectForTest src = new SampleObjectForTest();
  String json = gson.toJson(src);
  System.out.println(json);
}

輸出是:

{"longField":1234}

JSON 字段命名支持

Gson 支持一些預(yù)定義的字段命名策略,以將標準 Java 字段名稱(即以小寫字母 --- 開頭的駝峰名稱sampleFieldNameInJava)轉(zhuǎn)換為 Json 字段名稱(即sample_field_name_in_javaSampleFieldNameInJava)治笨。有關(guān)預(yù)定義命名策略的信息驳概,請參閱FieldNamingPolicy類。

它還具有基于注釋的策略旷赖,允許用戶基于每個字段定義自定義名稱顺又。請注意,基于注釋的策略具有字段名稱驗證等孵,如果提供了無效的字段名稱作為注釋值稚照,則會引發(fā) “運行時” 異常。

以下是如何使用兩個 Gson 命名策略功能的示例:

private class SomeObject {
  @SerializedName("custom_naming") private final String someField;
  private final String someOtherField;

  public SomeObject(String a, String b) {
    this.someField = a;
    this.someOtherField = b;
  }
}

SomeObject someObject = new SomeObject("first", "second");
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
String jsonRepresentation = gson.toJson(someObject);
System.out.println(jsonRepresentation);

輸出是:

{"custom_naming":"first","SomeOtherField":"second"}

如果您需要自定義命名策略(請參閱此討論)俯萌,可以使用@SerializedName的注解果录。

在自定義序列化器和反序列化器之間共享狀態(tài)

有時您需要在自定義序列化器 / 反序列化器之間共享狀態(tài)(請參閱此討論)。您可以使用以下三種策略來完成此任務(wù):

  1. 在靜態(tài)字段中存儲共享狀態(tài)
  2. 將序列化器 / 反序列化器聲明為父類型的內(nèi)部類咐熙,并使用父類型的實例字段來存儲共享狀態(tài)
  3. 使用 Java ThreadLocal

1 和 2 不是線程安全選項弱恒,但 3 是。

除了 Gson 的對象模型和數(shù)據(jù)綁定之外棋恼,您還可以使用 Gson 讀取和寫入返弹。您還可以組合流和對象模型訪問锈玉,以獲得兩種方法中的最佳方法。

在設(shè)計 Gson 時遇到的問題

有關(guān)我們在設(shè)計 Gson 時遇到的問題的討論义起,請參閱Gson 設(shè)計文檔拉背。它還包括 Gson 與可用于 Json 轉(zhuǎn)換的其他 Java 庫的比較。

Gson 未來的改進

有關(guān)最新的更新計劃或者如果你有新的建議默终,請參閱項目網(wǎng)站下的 Issues椅棺。部分

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市穷蛹,隨后出現(xiàn)的幾起案子土陪,更是在濱河造成了極大的恐慌,老刑警劉巖肴熏,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鬼雀,死亡現(xiàn)場離奇詭異,居然都是意外死亡蛙吏,警方通過查閱死者的電腦和手機源哩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸦做,“玉大人励烦,你說我怎么就攤上這事∑糜眨” “怎么了坛掠?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長治筒。 經(jīng)常有香客問我屉栓,道長,這世上最難降的妖魔是什么耸袜? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任友多,我火速辦了婚禮,結(jié)果婚禮上堤框,老公的妹妹穿的比我還像新娘域滥。我一直安慰自己,他們只是感情好蜈抓,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布启绰。 她就那樣靜靜地躺著,像睡著了一般沟使。 火紅的嫁衣襯著肌膚如雪酬土。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天格带,我揣著相機與錄音撤缴,去河邊找鬼刹枉。 笑死,一個胖子當著我的面吹牛屈呕,可吹牛的內(nèi)容都是我干的微宝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虎眨,長吁一口氣:“原來是場噩夢啊……” “哼蟋软!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嗽桩,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤岳守,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后碌冶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體湿痢,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年扑庞,在試婚紗的時候發(fā)現(xiàn)自己被綠了譬重。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡罐氨,死狀恐怖臀规,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情栅隐,我是刑警寧澤塔嬉,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站租悄,受9級特大地震影響谨究,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恰矩,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望憎蛤。 院中可真熱鬧外傅,春花似錦、人聲如沸俩檬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棚辽。三九已至技竟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屈藐,已是汗流浹背榔组。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工熙尉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搓扯。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓检痰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锨推。 傳聞我的和親對象是個殘疾皇子铅歼,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 為了更好的學(xué)習(xí)Gson,特將Gson User Guide翻譯如下换可。由于本人英文水平有限椎椰,如有錯誤,還請指正沾鳄,謝謝...
    WeberLisper閱讀 6,804評論 0 6
  • 1.概述2.Gson的目標3.Gson的性能和擴展性4.Gson的使用者5.如何使用Gson 通過Maven來使用...
    人失格閱讀 14,231評論 2 18
  • 前言 “設(shè)計模式”這四個字慨飘,對于使用面向?qū)ο笳Z言進行軟件開發(fā)的程序員來說絕不會陌生,不過對于很多經(jīng)驗尚淺的而言也僅...
    Caltortoise閱讀 843評論 0 3
  • Android中Gson的使用 1 簡介 Gson是一個Java庫洞渔,作用是將Java對象轉(zhuǎn)換成它對應(yīng)的JSON表示...
    LuckyXiang閱讀 19,976評論 2 3
  • 這是我姥爺給我講過的故事—— 說套媚,很久以前,有一個年輕人叫張三磁椒,父母死的早堤瘤,家里窮,沒有媳婦浆熔,靠給地主打短工過日子...
    鄉(xiāng)上閱讀 447評論 1 1