https://github.com/google/gson/blob/master/UserGuide.md#TOC-InstanceCreator-for-a-Parameterized-Type
api地址http://www.javadoc.io/doc/com.google.code.gson/gson/2.6.2
gson是一个用来将JAVA对象转换成JSON串的JAVA库,它也可以用来将JSON字符串转换为Java对象。
gson可以对任意的java对象转换,包括预先存在的没有源代码java对象。
提供易于使用的像toString()和构造函数(工厂方法)机制的Java转换成JSON,反之亦然
允许预先存在的不可修改的对象实现JSON和对象之间互转
允许自定义转换
支持任何复杂对象
生成紧凑,可读的JSON输出
四、Gson性能和可伸缩性
以下是我们在台式机(双核处理器,8GB内存,64位的Ubuntu)上获得了一些指标。您可以通过使用类PerformanceTest重新运行这些测试。
Strings: 反序列化超过25MB strings 没有发生问题(参考 PerformanceTest中的disabled_testStringDeserializationPerformance 方法 )
Large collections:
序列化包含1400000个对象的collection (参考 PerformanceTest中的disabled_testLargeCollectionSerialization 方法)
反序列化包含87,000个对象的colection (参考 PerformanceTest中的disabled_testLargeCollectionDeserialization 方法 )
Gson 1.4 反序列化byte数组和collection的大小从80k增加到了11MB。
注意: 运行test的时候需要删除disabled_ 前缀. 我们使用这个前缀,防止每次运行时都运行这些单元测试。
五、Gson 用户
GSON原本是为谷歌内部使用创建的,目前在许多项目中都使用的。使用的一些公共项目和公司
六、Gson的使用
1、配置
<dependencies> <!-- Gson: Java to Json conversion --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.6.2</version> <scope>compile</scope> </dependency> </dependencies>
// http://mvnrepository.com/artifact/com.google.code.gson/gson compile group: 'com.google.code.gson', name: 'gson', version: '2.6.2'
// 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);
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
推荐使用private字段
没有必要使用任何注解来标注序列化和反序列化。在当前的类(和所有父类)的所有字段默认情况下都会被序列化和反序列化
如果一个字段被标记为transient,默认情况它被忽略,不包括在JSON序列化和反序列化中。
能正确处理空值
序列化过程中,输出中的空字段会被忽略
反序列化中,如果json串中缺少实体,反序列化为对象之后对应属性为null
合成字段在序列化和反序列化过程中会被忽略。
内部类,匿名类和局部类外类的字段被忽略,不会被序列化和反序列化
Gson可以简单的序列化静态内部类,Gson也可以反序列化静态嵌套类。然而,GSON不能自动反序列化纯内部类,因为他们的无参数的构造还需要外部类的引用。可以通过定义静态内部类,或提供一个自定义InstanceCreator解决这个问题。下面是一个例子:
public class A { public String a; class B { public String b; public B() { // No args constructor for B } } }
Gson不能将{"b":"abc"} 反序列化为B的实例,因为B类是一个普通内部类,如果将B类定义为static的,就能正常反序列化。另一种方法是自定义构建器
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(); } }虽然能正常使用,但是不推荐用这种方式
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
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需要特别注意,需要明确集合元素类型。不幸的是,在Java中有没有办法来解决这个问题。
GSON可以序列任意对象的集合,但不能从直接反序列化,因为没有办法让用户指定生成的对象的类型。而反序列化,集合需要是泛型。遵循良好的Java编码实践时,减少问题。
当调用toJson(obj)的时候,Gson调用obj.getClass()获取序列化属性的信息,也可以直接将对应的类传给fromJson方法,在不是泛型的时候,很实用。
如果对象是泛型,由于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上面的代码将失败,因为GSON调用list.getClass()来获得它的类信息来解释值类型,但这个方法返回一个原始的类
可以通过为你的泛型类型指定正确的参数化类型解决这个问题。您可以通过使用TypeToken类做到这一点。
Type fooType = new TypeToken<Foo<Bar>>() {}.getType(); gson.toJson(foo, fooType); gson.fromJson(json, fooType);获取fooType的方法实际上定义了GetType的匿名局部内部类,返回完整的参数类型。
有时候会定义包含多种类型的Json数组,例如: ['hello',5,{name:'GREETINGS',source:'guest'}]
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; } }你可以简单调用toJson(collection)序列化collection,将得到想要的输出。
(3)为MyCollectionMemberType注册用一个适配器,传入 Collection<MyCollectionMemberType>调用fromJson().这种做法实际是只有当数组元素为顶级元素才能正常,或者如果你可以改变字段类型,持有集合<MyCollectionMemberType>的类型。
先翻译到这里,剩下的内容在下篇翻译
欢迎扫描二维码,关注公众号