Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨。

1.Java序列化与反序列化

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。

2.为什么需要序列化与反序列化

我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。

当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

3.如何实现Java序列化与反序列化

1)JDK类库中序列化API

java.io.ObjectOutputStream:表示对象输出流

它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

java.io.ObjectInputStream:表示对象输入流

它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。

2)实现序列化的要求

只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常。

3)实现Java对象序列化与反序列化的方法

假定一个Student类,它的对象需要序列化,可以有如下三种方法:

方法一:若Student类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化

ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。

ObjcetInputStream采用默认的反序列化方式,对对Student对象的非transient的实例变量进行反序列化。

方法二:若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。

ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。

方法三:若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。

ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。

4)JDK类库中序列化的步骤

步骤一:创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:

ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\\objectfile.obj”));

步骤二:通过对象输出流的writeObject()方法写对象:

out.writeObject(“Hello”);

out.writeObject(new Date());

5)JDK类库中反序列化的步骤

步骤一:创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:

ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\\objectfile.obj”));

步骤二:通过对象输出流的readObject()方法读取对象:

String obj1 = (String)in.readObject();

Date obj2 = (Date)in.readObject();

说明:为了正确读取数据,完成反序列化,必须保证向对象输出流写对象的顺序与从对象输入流中读对象的顺序一致。

为了更好地理解Java序列化与反序列化,选择方法一编码实现。

Student类定义如下:

package com.jieke.io;

import java.io.Serializable;

/**

*Title:学生类

*Description:实现序列化接口的学生类

*Copyright: copyright(c) 2012

*Filename: Student.java

*@author Wang Luqing

*@version 1.0

*/

public class Student implements Serializable

{

private String name;

private char sex;

private int year;

private double gpa;

public Student()

{

}

public Student(String name,char sex,int year,double gpa)

{

this.name = name;

this.sex = sex;

this.year = year;

this.gpa = gpa;

}

public void setName(String name)

{

this.name = name;

}

public void setSex(char sex)

{

this.sex = sex;

}

public void setYear(int year)

{

this.year = year;

}

public void setGpa(double gpa)

{

this.gpa = gpa;

}

public String getName()

{

return this.name;

}

public char getSex()

{

return this.sex;

}

public int getYear()

{

return this.year;

}

public double getGpa()

{

return this.gpa;

}

}

把Student类的对象序列化到文件O:\\Java\\com\\jieke\\io\\student.txt,并从该文件中反序列化,向console显示结果。代码如下:

import java.io.*;

/**

*Title:应用学生类

*Description:实现学生类实例的序列化与反序列化

*Copyright: copyright(c) 2012

*Filename: UseStudent.java

*@author Wang Luqing

*@version 1.0

*/

public class UseStudent

{

public static void main(String[] args)

{

Student st = new Student("Tom",'M',20,3.6);

File file = new File("O:\\Java\\com\\jieke\\io\\student.txt");

try

{

file.createNewFile();

}

catch(IOException e)

{

e.printStackTrace();

}

try

{

//Student对象序列化过程

FileOutputStream fos = new FileOutputStream(file);

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(st);

oos.flush();

oos.close();

fos.close();

//Student对象反序列化过程

FileInputStream fis = new FileInputStream(file);

ObjectInputStream ois = new ObjectInputStream(fis);

Student st1 = (Student) ois.readObject();

System.out.println("name = " + st1.getName());

System.out.println("sex = " + st1.getSex());

System.out.println("year = " + st1.getYear());

System.out.println("gpa = " + st1.getGpa());

ois.close();

fis.close();

}

catch(ClassNotFoundException e)

{

e.printStackTrace();

}

catch (IOException e)

{

e.printStackTrace();

}

}

}

结果如下所示:

name = Tom

sex = M

year = 20

gpa = 3.6

总结:

1)Java序列化就是把对象转换成字节序列,而Java反序列化就是把字节序列还原成Java对象。

2)采用Java序列化与反序列化技术,一是可以实现数据的持久化,在MVC模式中很是有用;二是可以对象数据的远程通信。

java 序列化概念和作用_结合代码详细解读Java序列化与反序列化概念理解相关推荐

  1. java中execution的作用_一文初步了解Java虚拟机

    大家都知道,Java中JVM的重要性,学习了JVM你对Java的运行机制.编译过程和如何对Java程序进行调优相信都会有一个很好的认知. 什么是JVM? JVM(Java Virtual Machin ...

  2. mapbox 修改初始位置_一行代码教你如何随心所欲初始化Bert参数(附Pytorch代码详细解读)...

    微信公众号:NLP从入门到放弃 微信文章在这里(排版更漂亮,但是内置链接不太行,看大家喜欢哪个点哪个看吧): 一行代码带你随心所欲重新初始化bert的参数(附Pytorch代码详细解读)​mp.wei ...

  3. 线性规划单纯形法python实现与代码详细解读

    线性规划单纯形法python实现与代码详细解读 1 单纯形法(Simplex method) 2 编程思路 3 python实现原理解读 4 python代码 5 后记 1 单纯形法(Simplex ...

  4. 基于pytorch搭建多特征CNN-LSTM时间序列预测代码详细解读(附完整代码)

    系列文章目录 lstm系列文章目录 1.基于pytorch搭建多特征LSTM时间序列预测代码详细解读(附完整代码) 2.基于pytorch搭建多特征CNN-LSTM时间序列预测代码详细解读(附完整代码 ...

  5. java如何编写windows木马_如何编写可怕的 Java 代码?

    原标题:如何编写可怕的 Java 代码? 作者:武培轩 我决定告诉你如何编写可怕的Java代码.如果你厌倦了所有这些美丽的设计模式和最佳实践,并且想写些疯狂的东西,请继续阅读. 如果你正在寻找有关如何 ...

  6. 定义一个dto对象_业务代码的救星——Java 对象转换框架 MapStruct 妙用

    在业务项目的开发中,我们经常需要将 Java 对象进行转换,比如从将外部微服务得到的对象转换为本域的业务对象 domainobject,将 domainobject 转为数据持久层的 dataobje ...

  7. java字符流字节流场景_【120期】Java IO:字节流、字符流、缓冲流

    IO流是Java中的一个重要构成部分,也是我们经常打交道的.这篇关于Java IO的博文干货满满,堪称全网前三(请轻喷!) 下面几个问题(问题还会继续补充),如果你能对答如流,那么恭喜你,IO知识掌握 ...

  8. java webservice报文过长_工作1-5年的Java程序猿到底需要怎样的一个技术栈?

    工作1-5年的Java程序猿到底需要怎样的一个技术栈? 前言: 具有1-5年开发经验的程序员 需要学习的内容其实还有很多很多. 今天跟大家交流一下希望分享出来的对大家能够有帮助,这是我这些年总结出的一 ...

  9. java实现次方的运算_【技术干货】Java 面试宝典:Java 基础部分(1)

    海牛学院的 | 第 616 期 本文预计阅读 |18 分钟 Java 基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法, ...

最新文章

  1. 安装sql server 2008 报错
  2. 【转帖】漫话C++0x(四) —- function, bind和lambda
  3. 【java机器学习】svm入门十讲
  4. The Process class relies on proc_open, which is not available on your PHP installation.
  5. 比特币价格疯涨!特斯拉或将支持比特币付款
  6. 10-300-020-简介-架构-简介
  7. c:forTokens
  8. java计算交点高程_卡西欧9860CG20图形计算程序(直线相交求交点坐标程序、距离后方交会带高程程序)...
  9. 华旭 身份证读卡器测试软件_华旭HX-FDX3S读卡器驱动+身份证验证软件
  10. vue axios封装及使用
  11. eyoucms相关问题总结
  12. 贴片钽电容耐压不符会导致爆炸
  13. 技术成长-不积跬步无以至千里
  14. 服务器获取百度商桥消息,百度统计和百度商桥什么关系?怎么部署同一段代码实现统计和商桥弹窗?...
  15. requestLayout() improperly called by…view.NoScrollGridView during layout: running second layout pass
  16. pandas基础用法详解
  17. 基于Matlab的空中交通管制仿真(附源码)
  18. 狂神说docker 常用命令笔记
  19. 显卡的游戏性能看什么参数
  20. office@word官方文档查看@审阅@批注@修订

热门文章

  1. web页面密码修改测试
  2. 牛客网——华为机试(题17:坐标移动)(Java)
  3. 【笔记】jstree插件的基本使用
  4. CentOS在安装配置 Ngnix_tomcat_PHP_Mysql
  5. LINQ标准查询操作符
  6. UA PHYS515A 电磁理论V 电磁波与辐射6 波导
  7. UA MATH567 高维统计I 概率不等式4 亚高斯分布
  8. 超图iServer服务管理概述
  9. VC2019无法打开文件msvcrtd.lib和Spectre 缓解库相关问题
  10. codesmith学习总结