以下内容来之官网翻译,地址

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基础知识的更多相关文章

  1. java使用类序列化反序列化(读写文件)

    创建类:Role package com.wbg.springRedis.entity; import java.io.Serializable; public class Role implemen ...

  2. Java安全之SnakeYaml反序列化分析

    Java安全之SnakeYaml反序列化分析 目录 Java安全之SnakeYaml反序列化分析 写在前面 SnakeYaml简介 SnakeYaml序列化与反序列化 常用方法 序列化 反序列化 Sn ...

  3. 【Java基础】序列化与反序列化深入分析

    一.前言 复习Java基础知识点的序列化与反序列化过程,整理了如下学习笔记. 二.为什么需要序列化与反序列化 程序运行时,只要需要,对象可以一直存在,并且我们可以随时访问对象的一些状态信息,如果程序终 ...

  4. Java做acm所需要的基础知识之排序问题

    Java做acm所需要的基础知识. 以前做acm的题都是用C/C++来写代码的,在学习完Java之后突然感觉Java中的方法比C/C++丰富很多,所以就整理一下平时做题需要用到的Java基础知识. 1 ...

  5. JAVA基础之——序列化和反序列化

    1 概念 序列化,将java对象转换成字节序列的过程. 反序列化,将字节序列恢复成java对象的过程. 2 为什么要序列化? 2.1 实现数据持久化,当对象创建后,它就会一直在,但是在程序终止时,这个 ...

  6. Java基础系列——序列化(一)

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6797659.html 工作中发现,自己对Java的了解还很片面,没有深入的研究,有很多的J ...

  7. JAVA反序列化漏洞基础原理

    JAVA反序列化漏洞基础原理 1.1 什么是序列化和反序列化? Java序列化是指把Java对象转换为字节序列的过程: Java反序列化是指把字节序列恢复为Java对象的过程: 1.2 为什么要序列化 ...

  8. python 全栈开发,Day32(知识回顾,网络编程基础)

    一.知识回顾 正则模块 正则表达式 元字符 : . 匹配除了回车以外的所有字符 \w 数字字母下划线 \d 数字 \n \s \t 回车 空格 和 tab ^ 必须出现在一个正则表达式的最开始,匹配开 ...

  9. 【学习笔记】Linux基础(零):预备知识

    学习笔记(连载)之Linux系列 Note:本学习笔记源自<鸟哥的Linux私房菜(基础学习篇)>一书,为此书重要内容的摘要和总结,对于一些常识性的知识不再归纳 新型冠状病毒引发的肺炎战& ...

随机推荐

  1. Linux 进程打开最大文件连接数Too many open files

    首先出现这个提示的原因:应用程序打开的文件数量超过了系统设定值. 如何查看当前系统每个用户最大允许打开文件数量: [root@registry ~]# ulimit -a core file size ...

  2. python域名200检测

    import requests import threading import queue # qianxiao996精心制作 #博客地址:https://blog.csdn.net/qq_36374 ...

  3. Java9至17的新特性总结

    总览 讲讲Java 9-17 的一些语法糖和一些新发布的jeps, 重点讲讲JVM的垃圾回收器 时间线 SpringBoot 为什么选择Java17这个版本.我估计跟下面这个图有关系. Java 8 ...

  4. Linux 中进程有哪几种状态?在 ps 显示出来的信息中,分别用什么符号表示的?

    (1)不可中断状态:进程处于睡眠状态,但是此刻进程是不可中断的.不可中断,指进程不响应异步信号. (2)暂停状态/跟踪状态:向进程发送一个 SIGSTOP 信号,它就会因响应该信号 而进入 TASK_ ...

  5. Dubbo 和 Dubbox 之间的区别?

    Dubbox 是继 Dubbo 停止维护后,当当网基于 Dubbo 做的一个扩展项目,如 加了服务可 Restful 调用,更新了开源组件等.

  6. 为什么要用 Spring Boot?

    Spring Boot 优点非常多,如:独立运行简化配置自动配置无代码生成和XML配置应用监控上手容易Spring Boot 集这么多优点于一身,还有理由不使用它呢?

  7. 深入理解Java虚拟机-垃圾收集算法

    一.判断对象是否可进行回收 1.引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的.但是主流的 ...

  8. switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

    答:在Java 5以前,switch(expr)中,expr只能是byte.short.char.int.从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始 ...

  9. springboot 定时任务 session报错问题

    一.自定义类 LocalVariable package com.lh.mes.base.thread; import java.util.Optional; public class LocalVa ...

  10. MySQL_fetch_array 和 MySQL_fetch_object 的区别是 什么?

    以下是 MySQL_fetch_array 和 MySQL_fetch_object 的区别: MySQL_fetch_array() – 将结果行作为关联数组或来自数据库的常规数组返回. MySQL ...