Java IO---序列化和反序列化
一.序列化和反序列化介绍
什么是序列化和反序列化?
序列化就是将对象转换为字节序列的过程。
反序列化就是将字节序列恢复为对象的过程。
序列化的用途在哪?
通常情况下,序列化有两个用途:
- 将对象的字节序列永久的保存到硬盘上,一般存在一个文件中。
- 在网络中传送对象的字节序列。
序列化的意义?
序列化机制使得对象可以脱离程序的运行而独立存在,能够离开内存空间,以便能长期保存。
比如:一个记录用户信息设置的类,当程序退出后下次再运行要保留上次的信息设置,此时就可以把这个类作为配置文件存在磁盘上,每次运行时再读取。
二.序列化和反序列化要点
序列化接口(Serializable)
要序列化的对象必须实现Serializable接口,否则将出现异常NotSerializableException,无法序列化
transient关键字
注意并不是所有的元素都需要序列化,当某些元素不需要序列化时,可以使用transient关键字修饰,被transient修饰的元素,不会进行jvm默认的序列化。
jvm是否允许反序列化,不仅与类的路径和功能代码是否一致相关,更重要的是类的序列化ID是否一致,也就是
private static final long serialVersionUID
序列化ID有两种生成策略:一种是固定的1L,一种是随机生成一个不重复的long类型数据;
建议是:没有特殊需求就使用默认的1L。
序列化不保存静态变量。
因为序列化保存的是对象的状态,静态变量是属于类的状态的,因此序列化不会保存静态变量。
这篇文章讲的比较清晰,个人觉得不错:[Java 序列化的高级认识(转载)]
三.序列化和反序列化使用
序列化的实现方式:
java.io.ObjectOutputStream
类,继承自OutputStream,将Java对象的原始数据类型写到文件,实现对象的持久化存储。构造方法:
ObjectOutputStream(OutputStream out)
:创建写入指定 OutputStream 的 ObjectOutputStream序列化写出对象方法:
public final void writeObject(Object obj)
:将指定的对象写入 ObjectOutputStream。序列化操作步骤:
- 创建一个ObjectOutputStream输出流。
- 调用ObjectOutputStream对象的writeObject输出可序列化对象。
示例:
import java.io.Serializable; public class Person implements Serializable{
public static final long serialVersionUID = 1L;
public String name;
public int age; public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
import java.io.*; public class TestObjectOutputStream {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
Person p = new Person("zhangsan", 20);
Person p1 = new Person("lisi", 30); oos.writeObject(p);
oos.writeObject(p1); oos.close();
}
}
反序列化的实现方式:
java.io.ObjectInputStream
类,继承自InputStream,将之前使用ObjectOutputStream序列化的原始数据恢复为对象 。构造方法:
ObjectInputStream(InputStream in)
:创建从指定InputStream读取的ObjectInputStream。反序列化读出对象方法:
public final Object readObject()
: 从 ObjectInputStream 读取对象。反序列化操作步骤:
- 创建一个ObjectInputStream输入流。
- 调用ObjectInputStream对象的readObject()得到序列化的对象。
示例1:读取上面序列化的Person实例化对象
import java.io.*; public class TestObjectInputStream {
public static void main(String[] args) throws IOException,ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt")); // 按写入的顺序读出
Person p = (Person)ois.readObject();
Person p1 = (Person)ois.readObject(); System.out.println("name:" + p.name + ",age:" + p.age);
System.out.println("name:" + p1.name + ",age:" + p1.age);
ois.close();
}
}
说明:
对于反序列化,在反序列化对象时候,必须是能够找到对应的class文件的类才行,如果找不到该类的class文件,则会抛出一个ClassNotFoundException。
反序列化还可能出现另一个异常:InvalidClassException。
可能的原因有以下几点:
- 该类的序列化ID与从流中读出来的序列化ID不一致(使用serialVersionUID解决)
- 该类含有未知数据类型
- 该类没有可访问的无参构造方法。
最新文章
- Blog 公用部分结构与class定义
- 在 Django 模板中遍历复杂数据结构的关键是句点字符
- oauth协议
- linux基本命令--学习记录
- asp.net的code-Behind技术
- 分层开发(MySchool总结)
- Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError
- zoj2589Circles(平面图的欧拉定理)
- codeforce Group Photo 2 (online mirror version)
- 使用Spring AOP预处理Controller的参数
- PHP获取文件行数
- CodeForces 510E Fox And Dinner
- NOIP2017 总结
- java面试3-对于java中值传递的理解(Hollis)
- WebDeploy to remote IIS
- SQL语句题
- 『Island 基环树直径』
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
- androidj基础:从网上下载图片
- Windows抓屏技术
热门文章
- linux禁止root用户直接登录
- ThinkPHP5框架引入的css等外部资源文件没有生效
- 逆向破解之160个CrackMe —— 028
- MobiSystems OfficeSuite 3.60.27307
- Detectron2源码阅读笔记-(三)Dataset pipeline
- 采坑复盘:logging日志能用封装后的函数来打日志,发现filename一直显示封装logging函数的方法所在的文件名
- 从0到1的开发,社交App 完成
- reduce方法和reduceRight方法
- Django API 自定义状态码
- 第05组 Beta冲刺(4/4)