序列化和反序列化(二)——Serializable 接口
Serializable 接口:该接口没有方法或字段,仅用于标识由该接口实现类创建的对象是可序列化的。
示例:
import java.io.Serializable;public class UserInfo implements Serializable {private static final long serialVersionUID = -564040236692883153L;private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "name='" + name + '\'' + ", age=" + age;}
}
import java.io.*;public class Test {/*** 序列化* * @author GaoHuanjie*/public static void serialize(){UserInfo userInfo = new UserInfo();userInfo.setAge(23);userInfo.setName("Tom");System.out.println(userInfo);ObjectOutput objectOutput = null;try {objectOutput = new ObjectOutputStream(new FileOutputStream("D:\\user_info.ser"));objectOutput.writeObject(userInfo);objectOutput.flush();} catch (IOException e) {e.printStackTrace();} finally {if (objectOutput!=null) {try {objectOutput.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 反序列化* * @author GaoHuanjie*/public static void deserialize(){ObjectInput objectInput = null;try {objectInput = new ObjectInputStream(new FileInputStream("D:\\user_info.ser"));UserInfo userInfo = (UserInfo) objectInput.readObject();System.out.println(userInfo);} catch (Exception e) {e.printStackTrace();} finally {if (objectInput!=null) {try {objectInput.close();} catch (IOException e) {e.printStackTrace();} }}}public static void main(String[] args) {serialize();//序列化deserialize();//反序列化}
}
serialVersionUID常量
实现Serializable接口的类须显式声明serialVersionUID常量,该常量作用如下:反序列化能否成功取决于三方面,首先序列化和反序列化类所在包相同,其次序列化和反序列化类的类名相同,最后序列化和反序列化类serialVersionUID的值要相同,两个类中的代码可以不同,如果不指定serialVersionUID,则类出现警告,但这是次要的,更重要的是序列化时将根据Java(TM)对象序列化规范为该类计算一个默认的serialVersionUID值,这就要求反序列化时使用的类与序列化时使用的类必须完全相同(有相同的属性和方法),否则反序列化失败,因为反序列化时serialVersionUID的值也是根据Java(TM)对象序列化规范计算出来的默认值,由于序列化类代码和反序列化类代码不同,则serialVersionUID的值肯定不同;但在实际开发中序列化类代码和反序列化类代码极有可能不同,在这种情况下为了反序列化成功就要求显式声明serialVersionUID常量且值要相同。serialVersionUID的生成策略有两种:一个是固定的 1L,一个是根据Java(TM)对象序列化规范生成的 long 类型数据;如果没有特殊需求,推荐使用固定值,这样便于序列化类代码和反序列化类serialVersionUID一致;如果限制某些用户的使用,则推荐第二种生成策略。
transient 关键字
在序列化时,transient 关键字修饰的成员变量不会被序列化;在反序列化时,transient 关键字修饰的成员变量被赋以默认值,如整型为0,浮点型为0.0,引用类型为null。
static关键字
在序列化时,static关键字修饰的成员变量不会被序列化。序列化保存的是对象的状态,静态变量属于类的状态,因此序列化并不保存静态变量,即序列化信息中不包含这个静态成员域。
import java.io.Serializable;public class UserInfo implements Serializable {private static final long serialVersionUID = 1L;private static int count;public UserInfo() {count++;}public String toString() {return "count:" + count;}
}
static修饰的成员变量,序列化和反序列化代码在一个进程中执行时会序列化成功,因为序列化时jvm已经把静态变量加载进来了,所以反序列化时获取的是加载好的静态变量,如下例子:
import java.io.*;public class Test {public static void main(String[] args) {try {ObjectOutput objectOutput = new ObjectOutputStream(new FileOutputStream("user_info.ser"));objectOutput.writeObject(new UserInfo());objectOutput.close();ObjectInput objectInput = new ObjectInputStream(new FileInputStream("user_info.ser"));UserInfo userInfo = (UserInfo) objectInput.readObject();System.out.println(userInfo);objectInput.close();} catch (Exception e) {e.printStackTrace();}}
}
static修饰的成员变量,序列化和反序列化代码不再一个进程,由于反序列化时是重新加载静态变量,所以静态变量是初始值,如下列子:
序列化:import java.io.*;public class Test1 {public static void main(String[] args) {try {ObjectOutput objectOutput = new ObjectOutputStream(new FileOutputStream("user_info.ser"));objectOutput.writeObject(new UserInfo());objectOutput.close();} catch (IOException e) {e.printStackTrace();}}
}反序列化:
import java.io.*;public class Test2 {public static void main(String[] args) {try {ObjectInput objectInput = new ObjectInputStream(new FileInputStream("user_info.ser"));UserInfo userInfo = (UserInfo) objectInput.readObject();System.out.println(userInfo);objectInput.close();} catch (Exception e) {e.printStackTrace();}}
}
序列化和反序列化(二)——Serializable 接口相关推荐
- 一起谈.NET技术,C#序列化与反序列化(Serializable and Deserialize)
序列化是指将对象实例的状态存储到存储媒体的过程.在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流.在随后对对象进行反序列化时,将创建出与 ...
- 对象序列化的 两种种方式(实现Serializable接口和实现Externalizable接口)
文章目录 1.方式一(实现Serializable接口,通过序列化流) 2.方式二 (实现Externalizable接口,重写writeExternal和readExternal方法) 对象序列化的 ...
- 装饰设计模式缓冲流转换流序列化与反序列化
装饰设计模式&缓冲流&转换流&序列化与反序列化 - 能够使用字节缓冲流读取数据到程序1.创建BufferedInputStream对象,构造方法中传递FileInputStre ...
- 【java笔记】序列化和反序列化
序列化: 写对象,把对象以流的方法写入到文件中 反序列化:读对象把文件中保存的对象,以流的方式读取出来 序列化和反序列化时,会抛出NotSerializableException没有序列化异常 类通过 ...
- ISerializable接口-控制序列化与反序列化(回答C#不需要实现此接口也可以序列化,那么实现该接口的意义是什么?)
https://www.cnblogs.com/fanfan-90/p/12038928.html (回答C#不需要实现此接口也可以序列化,那么实现该接口的意义是什么?) ISerializable接 ...
- 使用Json.Net处理json序列化和反序列化接口或继承类
以前一直没有怎么关注过Newtonsoft的Json.Net这个第三方的.NET Json框架,主要是我以前在开发项目的时候大多数使用的都是.NET自带的Json序列化类JavaScriptSeria ...
- Java 对象的序列化和反序列化
当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再 ...
- JavaSE——IO(下)(Properties类、序列化与反序列化)
第3节 IO(下) 一..properties文件与Properties类 1.1 .properties文件介绍 .properties文件一种属性文件,以键值对 的格式存储内容,在Java中可以使 ...
- 以ArrayList为例学习序列化和反序列化
一.序列化和反序列化: 在进行对象操作类的实现时,涉及到好几个关键词Serializable和transient 什么是序列化和反序列化? 序列化:将对象转化为字节的过程称为序列化过程 (存储到本地磁 ...
- Java对象的序列化和反序列化
[感谢]孤傲苍狼的 Java基础学习总结--Java对象的序列化和反序列化 一.序列化和反序列化的概念 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行 ...
最新文章
- 翻页导航条页码计算方法
- 2:0!谷歌 AI “AlphaStar“ 虐杀职业星际玩家
- Centos 7下编译安装Apache
- 从零开始入门 K8s | 手把手带你理解 etcd
- 数字信号处理学习笔记(五)|有限脉冲响应数字滤波器的设计
- 计算机基础知识题库选择题,计算机基础知识篇选择题库
- Windows上C++使用共享内存进行进程间通讯
- java.util.UnknownFormatConversionException: Conversion = ‘,‘ 解决
- 李洋疯狂C语言之合法帧
- IE6、IE7、IE8、Firefox通用关闭窗口js
- ssm项目中使用拦截器加上不生效解决方案
- Embedding技术在房产推荐中的应用(文末附PPT下载链接)
- css关键字unset
- Linux中mongodb定时远程备份
- Atitit 2018 技术趋势与没落技术总结 目录 1. 2018 技术雷达	1 1.1. HOSTED IDENTITY MANAGEMENT AS A SERVICE (SaaS)身份管理
- 清华山维EPS二次开发VBS基础篇
- SN1SLD16 华为SDH全新原包装2xSTM-16光接口板
- Linux数独小游戏C语言,C语言数独游戏的求解方法
- 如何往ncbi上上传数据
- Android 图片选取画图案