Java之Serializable接口实现序列化和反序列化实例以及部分序列化的四种方法

首先需要明确的概念:

  1. 序列化:将数据结构或对象转换成二进制字节流的过程
  2. 反序列化:将在序列化过程中所生成的二进制字节流的过程转换成数据结构或者对象的过程
  3. 持久化:将数据写入文件中长久保存的过程称之为持久化
  4. 序列化主要目的:是通过网络传输对象或者说是将对象存储到文件系统、数据库、内存中。
  • 序列化反序列化实例:

1.创建一个学生类实现Serializable接口:

public class Student implements Serializable {private String stuNum;private String stuName;//学生拥有多个老师 用集合装private List<String> teacherList;public Student() {}public Student(String stuNum, String stuName, List<String> teacherList) {this.stuNum = stuNum;this.stuName = stuName;this.teacherList = teacherList;}@Overridepublic String toString() {return "Student{" +"stuNum='" + stuNum + '\'' +", stuName='" + stuName + '\'' +", teacherList=" + teacherList +'}';}public String getStuNum() {return stuNum;}public void setStuNum(String stuNum) {this.stuNum = stuNum;}public String getStuName() {return stuName;}public void setStuName(String stuName) {this.stuName = stuName;}public List<String> getTeacherList() {return teacherList;}public void setTeacherList(List<String> teacherList) {this.teacherList = teacherList;}
}

2.创建SerializableUtil工具类实现序列化反序列化方法

public class SerializableUtil {/*** 将对象序列化到指定文件中* @param obj* @param fileName* @throws IOException*/public static void mySerialize(Object obj, String fileName) throws IOException {OutputStream out = new FileOutputStream(fileName);//对象序列化反序列化的流ObjectOutputStream objOut = new ObjectOutputStream(out);//将指定对象写入ObjectOutStreamobjOut.writeObject(obj);//关闭流objOut.close();}/*** 从指定文件中反序列化对象* @param fileName* @return* @throws IOException* @throws ClassNotFoundException*/public static Object myDeserialize(String fileName) throws IOException, ClassNotFoundException {InputStream in = new FileInputStream(fileName);ObjectInputStream objIn = new ObjectInputStream(in);Object obj = objIn.readObject();return obj;}
}

3.SerializableTest测试类,测试序列化反序列化实现

public class SerializableTest {public static void main(String[] args) {List<String> teacherList = new ArrayList<>();teacherList.add("王老师");teacherList.add("张老师");Student stu1 = new Student("1001", "张三", teacherList);System.out.println("原始对象:" + stu1);String fileName = "stu01.txt";try {//对象序列化SerializableUtil.mySerialize(stu1, fileName);System.out.println("序列化原始对象完成!OK!");//对象的反序列化Object obj = SerializableUtil.myDeserialize(fileName);//确定obj是Student类型if (obj instanceof Student) {Student stuNew = (Student) obj;System.out.println("反序列化之后的对象:" + stuNew);}} catch (Exception e) {e.printStackTrace();}}
}

4.测试结果:
生成stu01.txt文件,将数据结构成功转为二进制字节流存入文件中:
在这里插入图片描述

在这里插入图片描述


部分属性序列化和反序列化的四种方法

Transient关键字修饰

	private transient String stuNum;private transient String stuName;//学生拥有多个老师 用集合装private List<String> teacherList;

测试结果:
在这里插入图片描述

这里的stuNumStuName反序列化后就是默认值null,因为经过了transient修饰,阻止了属性的实例化,因此反序列结果中是null

对于不想进行序列化的变量,可以使用 transient 关键字修饰。
transient 关键字的作用是:让实例中的属性不再序列化;当对象被反序列化时,被 transient 修饰的属性不会被持久化和恢复。需要注意的一些点:

  • transient关键字只能修饰属性,不能修饰方法和类。
  • transient关键字修饰的属性变量,在经过反序列化之后会是相应类型的默认值,例如String类型反序列化后就是是nullint类型反序列化后就是0

Static关键字修饰

测试:

	private String stuNum;private static String stuName;//学生拥有多个老师 用集合装private List<String> teacherList;
public static void main(String[] args) {List<String> teacherList = new ArrayList<>();teacherList.add("王老师");teacherList.add("张老师");Student stu1 = new Student("1001", "张三", teacherList);System.out.println("原始对象:" + stu1);String fileName = "stu01.txt";try {//对象序列化SerializableUtil.mySerialize(stu1, fileName);System.out.println("序列化原始对象完成!OK!");stu1.setStuName("张三他爹");//对象的反序列化Object obj = SerializableUtil.myDeserialize(fileName);//确定obj是Student类型if (obj instanceof Student) {Student stuNew = (Student) obj;System.out.println("反序列化之后的对象:" + stuNew);}} catch (Exception e) {e.printStackTrace();}}

测试结果:
在这里插入图片描述

这里通过用static关键字修饰,直接在完成初始序列化后set.stuName可以改变学生名字,因为static修改的属性变量不属于任何对象,是静态的,因此无论使用transient与否,都不会被序列化。


修改默认方法writeObject和readObject

Serializable接口源码中有这样的说明
在这里插入图片描述

大概翻译一下writeObjectreadObject
在这里插入图片描述
在这里插入图片描述

测试:

public class Student implements Serializable {private String stuNum;private String stuName;private List<String> teacherList;private void writeObject(ObjectOutputStream objOut) throws IOException {System.out.println("writeObject-----------");objOut.writeObject(stuNum);objOut.writeObject(stuName);}private void readObject(ObjectInputStream objIn) throws IOException,ClassNotFoundException {System.out.println("readObject-----------");stuNum= (String) objIn.readObject();stuName= (String) objIn.readObject();}
}

测试结果:
在这里插入图片描述

因为在writeObjectreadObject方法中,只序列化和反序列化了stuNumstuName,因此teacherList是没有序列化反序列的,所以是String的默认值null


Externalizable实现序列化反序列化和部分序列化

Externalizable继承自Serializable,使用Externalizable接口需要实现readExternal方法和writeExternal方法来实现序列化和反序列化。

  • 源码部分
    在这里插入图片描述
  • 代码实现
private String stuNum;private String stuName;//学生拥有多个老师 用集合装private List<String> teacherList;@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(stuNum);out.writeObject(stuName);}@Overridepublic void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {stuNum= (String) in.readObject();stuName= (String) in.readObject();}

测试结果:
在这里插入图片描述

同样是因为writeExternal()readExternal()只序列化和反序列化了stuNumstuName,因此teacherList是没有序列化反序列的,所以是String的默认值null

Serializable 与 Externalizable

区别SerializableExternalizable
实现复杂度实现简单,Java对其有内建支持实现复杂,由开发人员自己完成
执行效率所有对象由Java统一保存,性能开发人员决定哪个对象保存,可能造成速度提升
保存信息保存时占用空间大部分存储,可能造成空间减少
使用频率偏低


关于序列化问题 Serializable

在修改公司项目的时候遇到这个问题,联想起之前做一篇博客。代码红线不贴了。

序列化的概念

序列化:把Java对象转换为字节序列的过程。
反序列化:把字节序列恢复为Java对象的过程。

序列化的方式

把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;(持久化对象)
在网络上传送对象的字节序列。(网络传输对象)

如何实现序列化

实现两个接口

Serializable 接口
Externalizable 接口

Serializable接口

一个对象想要被序列化,那么它的类就要实现此接口或者它的子接口。
这个对象的所有属性(包括private属性、包括其引用的对象)都可以被序列化和反序列化来保存、传递。
不想序列化的字段可以使用transient修饰。
由于Serializable对象完全以它存储的二进制位为基础来构造,因此并不会调用任何构造函数,因此Serializable类无需默认构造函数,但是当Serializable类的父类没有实现Serializable接口时,反序列化过程会调用父类的默认构造函数,因此该父类必需有默认构造函数,否则会抛异常

使用transient关键字阻止序列化虽然简单方便,但被它修饰的属性被完全隔离在序列化机制之外,导致了在反序列化时无法获取该属性的值,而通过在需要序列化的对象的Java类里加入writeObject()方法与readObject()方法可以控制如何序列化各属性,甚至完全不序列化某些属性或者加密序列化某些属性。

Externalizable 接口

它是Serializable接口的子类,用户要实现的writeExternal()和readExternal() 方法,用来决定如何序列化和反序列化。

因为序列化和反序列化方法需要自己实现,因此可以指定序列化哪些属性,而transient在这里无效

对Externalizable对象反序列化时,会先调用类的无参构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException: no valid constructor异常,因此Externalizable对象必须有默认构造函数,而且必需是public的。

serialVersionUID

serialVersionUID字段用来控制序列化的版本

一个对象数据,在反序列化过程中,如果序列化串中的serialVersionUID与当前对象值不同,则反序列化失败,否则成功。

如果serialVersionUID没有显式生成,系统就会自动生成一个。生成的输入有:类名、类及其属性修饰符、接口及接口顺序、属性、静态初始化、构造器。任何一项的改变都会导致serialVersionUID变化。

属性的变化都会导致自动生成的serialVersionUID发生变化。例如,对于对象A,我们生成序列化的S(A),然后修改A的属性,则此时A的serialVersionUID发生变化。反序列化时,S(A)与A的serialVersionUID不同,无法反序列化。会报序列号版本不一致的错误。

实现代码

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554738.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win10死机频繁怎么解决

Windows 10已经推出好几年&#xff0c;系统趋于稳定&#xff0c;但依旧不是完美&#xff0c;蓝屏、死机状态还是会出现&#xff0c;只是概率降低了很多&#xff0c;如果你的电脑遇到了突然死机或者频繁卡死的情况&#xff0c;或许你应该考虑对电脑进行重置了。系统自带的恢复重…

Jar包常见的反编译工具介绍与使用

反编译JAR能干什么: 排查问题、分析商业软件代码逻辑&#xff0c;学习优秀的源码思路。 反编译工具介绍 JD-GUI 下载地址&#xff1a;http://java-decompiler.github.io/ 点评&#xff1a;支持的java版本不会太高&#xff0c;中文注释能够正常显示。 Luyten 下载地址&#…

400 bad request的原因意思和解决方法

我们的电脑在使用的过程中&#xff0c;有的小伙伴在上网的时候可能就遇到过系统提示&#xff1a;400 bad request的情况。据小编所知这种情况&#xff0c;大致意思就是出现了错误的请求或者请求不能满足。原因是因为我们请求的语法格式出现呢错误或者其他情况等等。我们可以通过…

重装系统win10提示磁盘布局不受UEFI固件支持怎么办

原因分析&#xff1a; Win10系统新增UEFI检测机制&#xff0c;在BIOS开启了UEFI时&#xff0c;如果硬盘分区表格式不是GPT&#xff0c;则会提示无法重装系统win10&#xff0c;也就是说UEFIGPT或LegacyMBR才能安装win10。 解决方法一&#xff1a;关闭UEFI 1、重启系统时按Del…

win7按f8后没有进入安全模式怎么解决

win7f8后没有进入安全模式&#xff0c;在正确操作按F8没有进入安全模式之后&#xff0c;不知道怎么解决win7按f8后没有进入安全模式怎么解决&#xff0c;其实非常的简单&#xff0c;下面来看看详细的解决方法吧。 win7按f8后没有进入安全模式怎么解决 第一种方法&#xff1a;…

电脑开机就进入bios的解决方法

最近很多人反映自己的电脑一开机就直接进入bios里&#xff0c;无法正常进入系统。这是怎么回事呢?开机进入bios无法进入系统怎么办呢?别着急&#xff0c;今天就为大家带来电脑开机就进入bios的解决方法。 电脑开机就进入bios的解决方法&#xff1a; 1、如果是电脑的硬盘出了…

Serializable序列化和Externalizable序列化与反序列化的使用

1、序列化是干啥用的&#xff1f; 序列化的原本意图是希望对一个Java对象作一下“变换”&#xff0c;变成字节序列&#xff0c;这样一来方便持久化存储到磁盘&#xff0c;避免程序运行结束后对象就从内存里消失&#xff0c;另外变换成字节序列也更便于网络运输和传播&#xff…

Win10系统如何查看电脑是否是UEFI启动模式

Win10系统如何查看电脑是否是UEFI启动模式?现在越来越多的新电脑都采用UEFI来引导电脑系统&#xff0c;UEFI提高了开机后操作系统的启动速度&#xff0c;使电脑更加流畅&#xff0c;安全性更强&#xff0c;而传统的BIOS则没有UEFI用起来那么好。如何查看自己Win10系统电脑是否…

win10如何关闭Windows Defender安全保护程序

win10如何关闭Windows Defender安全保护程序&#xff1f;win10如何关闭Windows Defender安全保护程序?在安装的windows操作系统中&#xff0c;自带着安全保护程序“Windows Defender应用”&#xff0c;其实主要是为了保护好其他运行的软件&#xff0c;那该怎么来关闭这个软件呢…

2020-12-11

bios怎么恢复出厂设置? 1 第一步 打开电脑 在电脑出现开机提示时按下热键(一般是del或F2)就可以进入到bios设置界面 2 第二步 在bios设置界面中找到并选择“Load Optimized Default”&#xff0c; 然后按下回车键 3 第三步 在弹出窗口中选择“OK“ 然后回车键确定即可 …

JAVA序列化和反序列化的底层实现原理解析 更新时间:2019年11月27日 14:38:39 作者:myseries 这篇文章主要介绍了JAVA序列化和反序列化的底层实现原理解析,文中通

一、基本概念 1、什么是序列化和反序列化 &#xff08;1&#xff09;Java序列化是指把Java对象转换为字节序列的过程&#xff0c;而Java反序列化是指把字节序列恢复为Java对象的过程&#xff1b; &#xff08;2&#xff09;序列化&#xff1a;对象序列化的最主要的用处就是在…

笔记本电脑重启快捷键是什么

品牌型号&#xff1a;联想小新Air-14 2020 系统&#xff1a;win10 1909 64位企业版 部分用户可能电脑型号不一样&#xff0c;但系统版本一致都适合该方法。 用电脑用久了的朋友们都知道电脑的快捷键在哪里&#xff0c;笔记本电脑重启快捷键是什么?下面就给大家分享一下笔记…

新手iso系统怎么安装 新手安装iso镜像文件详细步骤

操作系统大多是iso格式的文件&#xff0c;尤其是Windows系统&#xff0c;都是.iso镜像&#xff0c;如果电脑可以正常使用&#xff0c;iso镜像文件只需解压出来就可以安装&#xff0c;但是对于新手来说&#xff0c;可能解压iso系统都是个问题&#xff0c;那么新手iso系统怎么安装…

Java获取一天的起止时间(Java8写法使用 LocalDateTime)

Calendar calendar new GregorianCalendar();// 0可以修改&#xff0c;0代表当前时间&#xff0c;-1代表前一天calendar.add(Calendar.DAY_OF_MONTH,0);//一天的开始时间 yyyy:MM:dd 00:00:00calendar.set(Calendar.HOUR_OF_DAY,0);calendar.set(Calendar.MINUTE,0);calend…

Windows10系统以太网显示“未识别的网络”如何解决

如果你的Win10系统电脑连不上网&#xff0c;那么可能会是三种情况导致的&#xff1a;受限未识别网络、拨号不成功或者网线没插好。其中&#xff0c;本地连接(以太网)提示“未识别的网络”情况是我们最经常碰到的。如果你的Win10系统无法访问网络&#xff0c;且在有线连接路由器…

如何在bios里调节风扇转速 bios设置风扇转速的方法

CPU的温度对电脑的正常运行有很大的影响&#xff0c;如果温度过高那么电脑就不能正常工作&#xff0c;风扇在降低温度中发挥着很大的作用&#xff0c;那么如何在bios里调节风扇转速呢?下面就给大家分享bios设置风扇转速的方法。 1、启动电脑按快捷键进入BIOS里面&#xff0c;…

win7开机黑屏怎么解决?win7开机黑屏出现reboot and select的解决方法

很多用户有遇见电脑黑屏的情况&#xff0c;而且还出现 reboot and select proper boot deviceor insert boot media in selected boot device 的提示&#xff0c;win7开机黑屏怎么解决呢?可能是硬盘接口数据线出现松动了&#xff0c;也可能是硬盘坏了。今天小编整理了相关的教…

win10系统进入监护人模式的方法

现在很多的小学生也会一直玩电脑很多家长就担心影响孩子学习因此想要设置监护人模式但是不知道win10系统监护人模式怎么进入&#xff0c;今天就给你们带来了win10系统进入监护人模式的方法&#xff0c;快来看看吧。 win10系统进入监护人模式的方法&#xff1a; 1、首先点击左…

解决win10电脑声音太小的问题

右击任务栏声音图标&#xff0c;点击选择菜单中的“播放设备”。 如果声音图标未显示&#xff0c;请在控制面板(大图标查看方式)中&#xff0c;点击选择“声音”。 在声音对话框&#xff0c;点击选中扬声器&#xff0c;然后点击下面的“属性”。 在扬声器 属性对话框&#xff0…

win7 ie临时文件夹怎么修改存放位置

首先&#xff0c;鼠标左键双击打开Internet Explorer,然后点击右上角的设置图标,点Internet选项。 打开之后&#xff0c;找到并点击“设置” 打开之后&#xff0c;找到并点击“移动文件夹” 然后找一个存放IE临时文件的位置,设好了之后点确定。 要让IE临时文件的移动生效,要对移…