共计 6232 个字符,预计需要花费 16 分钟才能阅读完成。
以下内容来之官网翻译,地址
1.Gson 依赖
1.1.Gradle/Android
dependencies {implementation 'com.google.code.gson:gson:2.9.0'}
1.2.maven
<dependencies> | |
<!-- Gson: Java to Json conversion --> | |
<dependency> | |
<groupId>com.google.code.gson</groupId> | |
<artifactId>gson</artifactId> | |
<version>2.9.0</version> | |
<scope>compile</scope> | |
</dependency> | |
</dependencies> |
1.2.Gson 简略实用
1.2.1. 根底类型
// Serialization | |
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] | |
// Deserialization | |
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); |
1.2.2. 对象
class BagOfPrimitives { | |
private int value1 = 1; | |
private String value2 = "abc"; | |
private transient int value3 = 3; | |
BagOfPrimitives() {// no-args constructor} | |
} | |
// Serialization | |
BagOfPrimitives obj = new BagOfPrimitives(); | |
Gson gson = new Gson(); | |
String json = gson.toJson(obj); | |
// ==> json is {"value1":1,"value2":"abc"} | |
// Deserialization | |
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class); | |
// ==> obj2 is just like obj |
Notes 如果对象内存在循环援用,序列化时将导致死循环。
例如:
@Data | |
public class RecursionObject { | |
private String name; | |
private RecursionReferObject refer; | |
} | |
@Data | |
public class RecursionReferObject { | |
private String name; | |
private RecursionObject refer; | |
} | |
public class GsonRecursionTest {public static void main(String[] args) {RecursionObject parent = new RecursionObject(); | |
parent.setName("1"); | |
RecursionReferObject son = new RecursionReferObject(); | |
son.setName("2"); | |
parent.setRefer(son); | |
son.setRefer(parent); | |
Gson gson = new GsonBuilder().create(); | |
String json=gson.toJson(parent); | |
System.out.println(json); | |
RecursionObject recursionObject=gson.fromJson(json,RecursionObject.class); | |
System.out.println(recursionObject); | |
} | |
} | |
/*** | |
Exception in thread "main" java.lang.StackOverflowError | |
at com.google.gson.stream.JsonWriter.string(JsonWriter.java:566) | |
at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:402) | |
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:417) | |
at com.google.gson.internal.bind.TypeAdapters$16.write(TypeAdapters.java:406) | |
at com.google.gson.internal.bind.TypeAdapters$16.write(TypeAdapters.java:390) | |
/** | |
阐明:
- 举荐对象字段应用根底类型
- 不须要增加给字段增加注解来示意该字段须要序列化,因为以后类 (所有父类) 中的所有字段默认都会被序列化
- 如果一个字段被标记为 transient,默认它在序列化 / 反序列化时会被疏忽
-
null 的解决
- 当序列化时,一个 null 字段会被省略
- 当反序列化时,如果一个字段找不到,则对应的对象字段会被设置为以下默认值:对象类型为 null,数值类型为 0,boolean 类型为 false
- 被 synthetic 标记的字段,也会在序列化 / 反序列化过程中被疏忽
- 外部类、匿名类、本地类所对应的外部类字段,在序列化 / 反序列化过程中也将会疏忽(这块没太了解)
1.2.3. 外部类(没看太懂)
Gson can serialize static nested classes quite easily.
Gson can also deserialize static nested classes. However, Gson can not automatically deserialize the pure inner classes since their no-args constructor also need a reference to the containing Object which is not available at the time of deserialization. You can address this problem by either making the inner class static or by providing a custom InstanceCreator for it. Here is an example:
public class A { | |
public String a; | |
class B { | |
public String b; | |
public B() {// No args constructor for B} | |
} | |
} |
NOTE: The above class B can not (by default) be serialized with Gson.
Gson can not deserialize {"b":"abc"}
into an instance of B since the class B is an inner class. If it was defined as static class B then Gson would have been able to deserialize the string. Another solution is to write a custom instance creator for B.
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(); | |
} | |
} |
The above is possible, but not recommended.
1.2.4.Array
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 |
反对多维。
1.2.5. 汇合
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 ints |
限度:gson 能够序列化任意对象的汇合,然而反序列化时须要指定汇合元素的类型。
1.2. 泛型
1.2.1.TypeToken 的应用
1.2.1.1. 对象类型的泛型
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 | |
Type fooType = new TypeToken<Foo<Bar>>() {}.getType(); | |
gson.toJson(foo, fooType); | |
gson.fromJson(json, fooType); |
通过 TypeToken 来定义泛型类型。
1.2.1.2. 汇合类型的泛型
@Data | |
public class Bar {private String name;} | |
public class GsonListTest {public static void main(String[] args) {Gson gson = new GsonBuilder().create(); | |
List<Bar> bars = new ArrayList<>(); | |
Bar bar = new Bar(); | |
bar.setName("bar 1"); | |
bars.add(bar); | |
String json = gson.toJson(bars); | |
System.out.println(json); | |
Type type = new TypeToken<List<Bar>>(){}.getType(); | |
List<Bar> dbars = gson.fromJson(json,type); | |
System.out.println(dbars); | |
} | |
} | |
/** | |
[{"name":"bar 1"}] | |
[Bar(name=bar 1)] | |
***/ |
1.2.2. 自定义 ParameterizedType
在理论我的项目中,如果应用大量应用 TypeToken,定义起来会比拟麻烦,查看 TypeToken 的底层源码,发现它也是通过 ParameterizedType 来实现的。(不懂 ParameterizedType 的能够先百度一下)
public class MyParameterizedType implements ParameterizedType {private Type[] args; | |
private Class rawType; | |
public MyParameterizedType(Class rawType,Type[] args) { | |
this.args = args; | |
this.rawType = rawType; | |
} | |
@Override | |
public Type[] getActualTypeArguments() {return args;} | |
@Override | |
public Type getRawType() {return rawType;} | |
@Override | |
public Type getOwnerType() {return null;} | |
} | |
// 测试简单泛型类型 | |
public class ParameterizedTypeTest {public static void main(String[] args) {Gson gson = new GsonBuilder().create(); | |
Result<List<Bar>> result = new Result<>(); | |
List<Bar> bars = new ArrayList<>(); | |
Bar bar = new Bar(); | |
bar.setName("bar 1"); | |
bars.add(bar); | |
result.setData(bars); | |
Type inner = new MyParameterizedType(List.class, new Class[]{Bar.class}); | |
MyParameterizedType type = new MyParameterizedType(Result.class,new Type[]{inner}); | |
String json = gson.toJson(result); | |
System.out.println(json); | |
Result<List<Bar>> result1=gson.fromJson(json,type); | |
System.out.println(result1); | |
} | |
} |
1.3.null 值解决
Gson gson = new GsonBuilder().serializeNulls().create(); | |
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 |