java基础知识-序列化/反序列化-gson基础知识
2022/4/9 11:19:02
本文主要是介绍java基础知识-序列化/反序列化-gson基础知识,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
以下内容来之官网翻译,地址
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
这篇关于java基础知识-序列化/反序列化-gson基础知识的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27消息中间件底层原理资料详解
- 2024-11-27RocketMQ底层原理资料详解:新手入门教程
- 2024-11-27MQ底层原理资料详解:新手入门教程
- 2024-11-27MQ项目开发资料入门教程
- 2024-11-27RocketMQ源码资料详解:新手入门教程
- 2024-11-27本地多文件上传简易教程
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器