序列化: 将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输。对象->字节序列

反序列化: 数据转化为对象。字节序列->对象

一、序列化简介

1、进行序列化的原因:

(1)网络传输

网络传输的数据都必须是二进制数据,但是在Java中都是对象,是没有办法在网络中传输的,所以就需要对Java对象进行序列化,并且要求这个序列化是可逆的,也就是说要可以进行反序列化,否则人家都不知道你传递的是啥信息

(2)对象持久化

将内存中的对象状态保存到文件或者数据库中

(3)实现分布式对象

如RMI(远程方法调用)要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样

2、实现序列化的方式

(1)Java原生序列化

需要被序列化的类实现Serializable接口

具体实现:

1)序列化

ObjectOutputStream#writeObject(Object obj)方法

2)反序列化

ObjectInputStream#readObject()方法

缺点:

效率较低,序列化后的流数据比较大

(2)使用第三方的序列化方式

如JSON、Hessian等

3、注意

(1)transient修饰的属性,是不会被序列化的

(2)静态static修饰的属性,是不会被序列化的

二、JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。

注意:

1)虽然 JSON 名称中有 JavaScript,但是 JSON 和 JavaScript 的关系仅仅只是 在设计JSON的时候参照了JavaScript的一些语法而已,两者无必然联系。

2)JSON常用于网络数据的交互,以及将某些数据按照JSON的格式写入到文件进行持久化记录

三、GSON

Github:https://github.com/google/gson

GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个JSON字符串转成一个Java对象(反序列化),或反过来(序列化)

在项目中引用GSON:

Gradle:

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

1、将对象转换为JSON字符串

在需要转换JSON字符串的位置编写代码:

String json = new Gson().toJSON(要转换的对象);

2、将JSON字符串转换为对象

在需要转换Java对象的位置编写代码:

对象 = new Gson().fromJson(JSON字符串, 对象类型.class);

接下来,将从以下几个方面来介绍 GSON 的使用:

  • Java Object 序列化/反序列化
  • Array 和 List 的序列化/反序列化
  • Map 和 Set 的序列化/反序列化
  • 变量值为null时的序列化/反序列化
  • 控制 序列化/反序列化 的变量名称

1、Java对象序列化与反序列化

public class User {@Exposeprivate String userName;@Exposeprivate String password;@Exposeprivate int age;@Exposeprivate boolean isStudent;@Exposeprivate Job job;//serialize,是否参与序列化;deserialize,是否参与反序列化@Expose(serialize=false, deserialize=false)private int test1;private transient int test2;//无法以class作为字段名@SerializedName("class")private int cls;public User(String userName, String password, int age, boolean isStudent){this.userName = userName;this.password = password;this.age = age;this.isStudent = isStudent;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public boolean isStudent() {return isStudent;}public void setStudent(boolean student) {isStudent = student;}public Job getJob() {return job;}public void setJob(Job job) {this.job = job;}public int getTest1() {return test1;}public void setTest1(int test1) {this.test1 = test1;}public int getTest2() {return test2;}public void setTest2(int test2) {this.test2 = test2;}public int getCls() {return cls;}public void setCls(int cls) {this.cls = cls;}@NonNull@Overridepublic String toString() {return "userName=" + userName + ", " +"password=" + password + ", " +"age=" + age + ", " +"isStudent=" + isStudent + ", " +"job=" + job + ", " +"test1=" + test1 + ", " +"test2=" + test2 + ", " +"cls=" + cls;}
public class ObjectUnitTest {public void testObject(){User u1 = new User("Lance", "123", 18, false);Gson gson = new Gson();//序列化String json = gson.toJson(u1);System.out.println("序列化:" + json);//反序列化User u2 = gson.fromJson(json, User.class);System.out.println("反序列化:" + u2.getUserName());System.out.println("反序列化:u2: " + u2);}public static void main(String args[]){ObjectUnitTest out = new ObjectUnitTest();out.testObject();}
}

结果:

序列化:{"userName":"Lance","password":"123","age":18,"isStudent":false,"test1":0,"class":0}
反序列化:u2: userName=Lance, password=123, age=18, isStudent=false, job=null, test1=0, test2=0, cls=0

Java嵌套对象序列化与反序列化

public class Job {private String name;private int salary;public Job(String name, int salary){this.name = name;this.salary = salary;}@Overridepublic String toString(){return "Job{" +"name='" + name + '\'' +", salary = " + salary +'}';}
}
    public void testNestedObject(){User u1 = new User("Lance", "123", 18, false);Job job = new Job("工人", 10000);u1.setJob(job);Gson gson = new Gson();String json = gson.toJson(u1);System.out.println("序列化::" + json);User u2 = gson.fromJson(json, User.class);System.out.println("反序列化::" +u2);}

结果:

序列化::{"userName":"Lance","password":"123","age":18,"isStudent":false,"job":{"name":"工人","salary":10000},"test1":0,"class":0}
反序列化::userName=Lance, password=123, age=18, isStudent=false, job=Job{name='工人', salary = 10000}, test1=0, test2=0, cls=0

2、Array 和 List 的序列化/反序列化

(1)Array数组的序列化与反序列化

数组类型对象和普通对象一样,使用toJson/fromJson即可完成序列化与返序列化

public void testArray(){User[] users1 = new User[3];users1[0] = new User("Lance", "123", 18, false);users1[1] = new User("Alex", "123", 88, true);Gson gson = new Gson();String json = gson.toJson(users1);System.out.println("序列化:" + json);User[] users2 = gson.fromJson(json, User[].class);System.out.println("反序列化:" + users2[0]);System.out.println("反序列化:" + users2[1]);System.out.println("反序列化:" + users2[2]);
}

结果:

序列化:[{"userName":"Lance","password":"123","age":18,"isStudent":false,"test1":0,"class":0},{"userName":"Alex","password":"123","age":88,"isStudent":true,"test1":0,"class":0},null]
反序列化:userName=Lance, password=123, age=18, isStudent=false, job=null, test1=0, test2=0, cls=0
反序列化:userName=Alex, password=123, age=88, isStudent=true, job=null, test1=0, test2=0, cls=0
反序列化:null

(2)List集合的序列化和反序列化

    public void testListObject(){List<User> list1 = new ArrayList<>();list1.add(new User("Lance", "123", 18, false));list1.add(new User("Alex", "123", 88, true));list1.add(null);Gson gson = new Gson();//序列化String json = gson.toJson(list1);System.out.println("List序列化:" + json);//反序列化Type type = new TypeToken<List<User>>(){}.getType();List<User> list2 = gson.fromJson(json, type);  //注意,这里是typeSystem.out.println("List反序列化:" + list2.get(0));System.out.println("List反序列化:" + list2.get(1));System.out.println("List反序列化:" + list2.get(2));}

结果:

List序列化:[{"userName":"Lance","password":"123","age":18,"isStudent":false,"test1":0,"class":0},{"userName":"Alex","password":"123","age":88,"isStudent":true,"test1":0,"class":0},null]
List反序列化:userName=Lance, password=123, age=18, isStudent=false, job=null, test1=0, test2=0, cls=0
List反序列化:userName=Alex, password=123, age=88, isStudent=true, job=null, test1=0, test2=0, cls=0
List反序列化:null

注意:

fromJson如果第二个参数为List.class的话,Gson不知道List中的泛型类型是什么,不知道接收数据是哪种类。

TypeToken将泛型指定为List中存储的类型。


3、Map 和 Set 的序列化/反序列化

(1)Map的序列化与反序列化

Map集合类型对象在反序列化时与List一样,需要使用TypeToken完成反序列化

public void testMapObject(){Map<String, User> map1 = new HashMap<>();//java对象map1.put("1", new User("Lance","123", 18, false));map1.put("2", new User("Alex","123", 88, true));map1.put("3",null);map1.put(null, null);//Gson提供的Gson对象Gson gson = new Gson();//序列化String json = gson.toJson(map1);System.out.println("Map序列化:" + json);Type type = new TypeToken<Map<String, User>>(){}.getType();Map<String, User> map2 = gson.fromJson(json, type);System.out.println("Map反序列化:" + map2.get(null));System.out.println("Map反序列化:" + map2.get("1"));}

结果:

Map序列化:{"1":{"userName":"Lance","password":"123","age":18,"isStudent":false,"test1":0,"class":0},"2":{"userName":"Alex","password":"123","age":88,"isStudent":true,"test1":0,"class":0}}
Map反序列化:null
Map反序列化:userName=Lance, password=123, age=18, isStudent=false, job=null, test1=0, test2=0, cls=0

(2)Set的序列化与反序列化

Set在反序列化时同样需要使用TypeToken完成反序列化

public void testSetObject(){Set<User> set1 = new HashSet<>();//java对象set1.add( new User("Lance","123", 18, false));set1.add(new User("Alex","123", 88, true));set1.add(null);//Gson提供的Gson对象Gson gson = new Gson();//序列化String json = gson.toJson(set1);System.out.println("Set序列化:" + json);反序列化
//        Type type = new TypeToken<List<User>>(){}.getType();
//        //如果是 HashSet 类型,则完全可以使用反序列为List,因为ArrayList和HashSet 两者序列化后的 Json 数据一致。
//        List<User> set2 = gson.fromJson(json, type);
//        System.out.println("Set反序列化:" + set2.get(0));
//        System.out.println("Set反序列化:" + set2.get(1));
//        System.out.println("Set反序列化:" + set2.get(2));//反序列化Type type = new TypeToken<Set<User>>(){}.getType();//Set需要使用迭代器,不能直接getSet<User> set2 = gson.fromJson(json, type);Iterator<User> iterator = set2.iterator();while(iterator.hasNext()){User next = iterator.next();System.out.println("Set反序列化:" + next);}}

结果:

Set序列化:[null,{"userName":"Lance","password":"123","age":18,"isStudent":false,"test1":0,"class":0},{"userName":"Alex","password":"123","age":88,"isStudent":true,"test1":0,"class":0}]
Set反序列化:null
Set反序列化:userName=Lance, password=123, age=18, isStudent=false, job=null, test1=0, test2=0, cls=0
Set反序列化:userName=Alex, password=123, age=88, isStudent=true, job=null, test1=0, test2=0, cls=0

4、变量值为null时的序列化/反序列化

(1)如果一个变量为NULL,那么按照 GSON 默认的处理为忽略这个字段

    public void testVarNull(){User u1 = new User("Lance", "123", 18, false);  //job字段没有赋值,默认为NULL//Gson提供的Gson对象Gson gson = new Gson();//序列化String json = gson.toJson(u1);System.out.println(json);//反序列化User u2 = gson.fromJson(json, User.class);System.out.println(u2);}

结果:

{"userName":"Lance","password":"123","age":18,"isStudent":false,"test1":0,"class":0}
userName=Lance, password=123, age=18, isStudent=false, job=null, test1=0, test2=0, cls=0

当某个属性为null时,Gson在序列化时会忽略这个属性

(2)如果一个集合中的存储的数据为NULL,那么按照GSON默认的处理为不会忽略

List<User> list1 = new ArrayList<>();
list1.add(new User("Lance", "123", 18, false));
list1.add(null);Gson gson = new Gson();//序列化
String json = gson.toJson(list1);
System.out.println("序列化:" + json);

结果:

序列化:[{"userName":"Lance","password":"123","age":18,"isStudent":false,"test1":0,"class":0},null]

5、控制序列化/反序列化的变量名称

(1)如果希望JSON字符串字段名不用变量名作为Key(比如User类的userName被作为Key),又或者希望JSON字符串中的Key存在Java中的关键字时(如 “class”:18),可以借助 @SerializedName 注解控制 JSON 字段中 Key 的命名。

class User{...@SerializedName("class")private int cls;
}

(2)如果希望指定GSON对某些字段配置是否参与序列化与反序列化,可以使用 @Expose 注解控制,同时使用 GsonBuilder 创建 Gson 对象。

可以点进去“@Expose”看下源码,可以发现可以设置变量是否参加 序列化/反序列化

默认情况下,变量是可以参加序列化/反序列化的

要使得 “@Expose” 生效,就不是 new Gson() 了,而是new GsonBuilder().excludeFieldWithoutExposeAnnotation().create();

(3)transient关键字的作用:使得变量不参加任何序列化/反序列化

Android基础学习(十五)—— 序列化与反序列化(包括 JSON、GSON))相关推荐

  1. JAVA基础学习(十五)--集合二--TreeSet和泛型

    一.TreeSet 1.1.TreeSet Set:hashSet:数据结构是哈希表.线程是非同步的. 保证元素唯一性的原理:判断元素的HashCode值是否相同. 如果相同,还会判断元素的equal ...

  2. Linux学习十五 DNS基础服务

    Linux学习十五 DNS基础服务 DNS服务基础 BIND 伯利克Internet 域名服务 主要执行程序:/usr/sbin/named 系统服务:named 默认端口: TCP/UDP 53 主 ...

  3. C++学习 十五、类继承(1)基类,派生类,访问权限,protected

    C++学习 十五.类继承(1)基类,派生类 前言 类继承 类的关系与继承 基类, 派生类 基类 派生类 构造函数,析构函数 文件位置 访问权限 protected 后记 前言 本篇开始学习C++类的继 ...

  4. Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition

    Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition Property animation系统还提供了对ViewGroup中的View改变 ...

  5. OpenCV与图像处理学习十五——LBP纹理特征(含代码)

    OpenCV与图像处理学习十五--LBP纹理特征(含代码) 一.LBP介绍 二.LBP原理 三.代码应用 一.LBP介绍 LBP(Local Binary Pattern, 局部二值模式) , 是一种 ...

  6. PyTorch框架学习十五——可视化工具TensorBoard

    PyTorch框架学习十五--可视化工具TensorBoard 一.TensorBoard简介 二.TensorBoard安装及测试 三.TensorBoard的使用 1.add_scalar() 2 ...

  7. JAVASE基础模块十五(StringBuffer类)

    JAVASE基础模块十五(StringBuffer类) public class Stbuffer { public static void main(String[] args) { //总共创建五 ...

  8. OpenGL入门学习(十五)

    OpenGL入门学习[十五] 这次讲的所有内容都装在一个立方体中,呵呵. 呵呵,绘制一个立方体,简单呀,我们学了第一课第二课,早就会了. 先别着急,立方体是很简单,但是这里只是拿立方体做一个例子,来说 ...

  9. 想要专升本你不得不看的全干货_吐血整理_专升本_计算机文化基础( 十 五 )

    大家好,我是阿Ken.很快就要整理完第三章了~ 对于专升本_计算机文化基础我已经在博客里整理了已经一半多了,希望能够在我整理后能够帮助其他的小伙伴,这月底整理完所有的专升本_计算机文化基础的笔记,感兴 ...

  10. 计算机推演未来发展动象,大学生计算机基础学习心得五篇

    学习作为一种获取知识交流情感的方式,已经成为人们日常生活中不可缺少的一项重要内容,尤其是在二十一世纪这个知识经济时代,自主学习已是人们不断满足自身需要.以下是小编整理的大学生计算机基础学习心得,希望可 ...

最新文章

  1. python中异常的姓名
  2. C#方法中参数ref和out的解析
  3. 机械硬盘低级格式化软件_低级比高级安全?磁盘格式化要保护秘密
  4. 能在微软的网站找到IeWebcontrols的安装文件吗
  5. linux上安装mysql5.7
  6. scrm电商后台管理、公司管理、店铺管理、特卖活动、营销活动、订单管理、优惠券管理、商品管理、会员管理、标签管理、会员卡、签到配置、积分、拼团、砍价、快递配置、短信配置、充值、运营活动
  7. 模板元实现顺序、分支和循环结构
  8. Linux中断处理“下半部”机制
  9. 数据结构视频教程 -《数据结构(邓俊辉)》
  10. 解决Tomcat严重: Parse error in application web.xml file at jndi:/localhost/ipws/WEB-INF/web.xml java.lan
  11. SDUCS经验分享未完结部分
  12. java判断移动端和pc端_Java判断PC端还是移动端
  13. Oracle表空间碎片查询以及整理
  14. 文光伏领军企业转型热切拥抱互联网
  15. [设计模式](十):策略模式(Strategy)与模板模式(Template)详解及二者间区别介绍(两种父子类行为模式)
  16. 用水泥混凝土摊铺机进行作业时该做到的日常养护工作
  17. 可裂解组织蛋白酶的ADC偶联物-靶向抗体偶联技术
  18. 股票历史数据-股票历史数据查询怎么查?怎么查股票历史数据?
  19. 全国计算机等级考试一级书,全国计算机等级考试一本通:一级MS OFFICE
  20. Windows10安装深度Linux,可能是最漂亮的国产Linux,windows下安装深度操作系统步骤...

热门文章

  1. Blue Coat推移动设备安全(MDS)服务
  2. 僵尸网络“Mykings”
  3. 7种网络摄像机的设计方案,包含软硬件设计
  4. python 方差_python+方差_python 方差_python 方差齐性检验 - 云+社区 - 腾讯云
  5. 关于符号Symbol第一篇
  6. 邮箱被国际反垃圾邮件组织拉黑的解决方法
  7. TypeError: Image data of dtype object cannot be converted to float
  8. 干货|TPM管理系列之六源改善
  9. 教你用Python批量下载音乐功能,无需安装播放器,直接下载!
  10. TiDB 压力测试报告