Java 序列化详解及简单实现实例
发布时间 - 2026-01-10 23:28:28 点击率:次一、序列化

序列化定义:序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
目的:
- 以某种存储形式使自定义对象持久化
- 将对象从一个地方传递到另一个地方
二、Java序列化
一个对象能够序列化的前提是实现Serializable接口。Serializable接口没有方法,更像是个标记。有了这个标记的Class就能被序列化机制处理。如下:
class myPoint implements Serializable{
}
JAVA反序列化不会调用任何构造器
序列化的控制:Externalizable。读写都交给你
- 要在方法writeExternal写入序列化的参数
- 要在方法readExternal读取反序列化的值
- 要有默认的构造方法(readExternal执行完成,再执行默认的构造器)
void writeExternal(ObjectOutput out) throws IOException;
void readExternal(ObjectInput in) throws IOException,ClassNotFoundException;
public class Point implements Externalizable {
private int a;
private int b;
public Point(int a, int b) {
this.a = a;
this.b = b;
}
public Point() {
}
public String toString() {
return a + " , " + b;
}
public void writeExternal(ObjectOutput out) throws IOException {
out.write(a);
out.write(b);
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
a = in.read();
b = in.read();
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
String file = "d://1.txt";
Point p = new Point(1, 2);
System.out.println(p);
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p);
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Point pp = (Point) ois.readObject();
System.out.println(pp);
}
}
- transient关键字 关闭序列化自动进行。
- 不管你选择了哪种序列化形式,都要为自己编写的每个可序列化的类声明一个显示的序列版本UID(serial version UID)
三、序列化的问题
在effective Java中列举出了java序列化要注意的一些问题:
1.谨慎地设计实现Serializable接口
- 实现发布了就是一种承诺
- 如果一个类是为继承设计的,在‘允许子类实现Serializable接口'与‘禁止子类实现Serializable接口'取一个折中的方案是:提供一个可访问的无参构造器
2.保护性地编写 readObject()方法,因为readObject()是构建实例的入口。
不保护可能出现 构建了不满足要求的 实例
3.考虑自定义的序列化形式
- 逻辑内容 与 物理表示法
- 如果一个对象的 ‘物理表示法'等同于它的‘逻辑内容',可能就适用于使用默认的序列化形式。
- 如果有更好的 ‘物理表示法'在表示‘逻辑内容'则可以自定义序列化形式。
public class StringList implements Serializable {
private transient int size = 0;
private transient Entity head = null;
public final void add(String str) {
// ...
}
private static class Entity {
String data;
Entity next;
Entity previous;
}
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.write(size);
for (Entity e = head; e != null; e = e.next) {
s.writeObject(e.data);
}
}
private void readObject(ObjectInputStream s) throws IOException,
ClassNotFoundException {
s.defaultReadObject();
int num = s.read();
for (int i = 0; i < num; i++) {
this.add((String) s.readObject());
}
}
}
四、序列化代理模式
序列化机制提供的钩子函数有:
writeReplace writeObject readObject readResolve
- writeReplace:序列化的时候替换所要序列化的对象。
- writeObject:写入序列化的对象
- readObject:读取序列化的对象
- readResolve:最后返回序列化对象
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Date;
public final class Period implements Serializable {
private static final long serialVersionUID = 100L;
private final Date start;
private final Date end;
public Period(Date start, Date end) {
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
if (this.start.compareTo(this.end) > 0) {
throw new IllegalArgumentException(start + " after " + end);
}
}
public Date start() {
return new Date(start.getTime());
}
public Date end() {
return new Date(end.getTime());
}
public String toString() {
return start + " - " + end;
}
// 不给
private Object writeReplace() {
return new SerializationProxy(this);
}
private void readObject(ObjectInputStream stream)
throws InvalidObjectException {
throw new InvalidObjectException("proxy request");
}
private static class SerializationProxy implements Serializable {
private final Date start;
private final Date end;
SerializationProxy(Period p) {
this.start = p.start;
this.end = p.end;
}
private Object readResolve() {
return new Period(start, end);
}
private static final long serialVersionUID = 1000L;
}
}
五、序列化算法
- 将对象实例相关的类元数据输出。
- 递归地输出类的超类描述直到不再有超类。
- 类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。
- 从上至下递归输出实例的数据
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Java序列化
# java
# 序列化实例
# 序列化详解
# java 中Spark中将对象序列化存储到hdfs
# 浅谈java中为什么实体类需要实现序列化
# 序列化版本号serialVersionUID的作用_动力节点Java学院整理
# 详解Java 对象序列化和反序列化
# Java 序列化和反序列化实例详解
# 浅谈Java序列化和hessian序列化的差异
# 序列化
# 递归
# 自定义
# 子类
# 要在
# 的是
# 是个
# 出了
# 就能
# 要有
# 适用于
# 这两个
# 要注意
# 希望能
# 不给
# 结合起来
# 谢谢大家
# 提供一个
# 则可
# 所要
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
C#如何调用原生C++ COM对象详解
常州企业网站制作公司,全国继续教育网怎么登录?
昵图网官方站入口 昵图网素材图库官网入口
如何快速配置高效服务器建站软件?
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?
如何为不同团队 ID 动态生成多个非值班状态按钮
公司网站制作价格怎么算,公司办个官网需要多少钱?
北京网站制作的公司有哪些,北京白云观官方网站?
js代码实现下拉菜单【推荐】
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
Android自定义控件实现温度旋转按钮效果
Laravel如何处理和验证JSON类型的数据库字段
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
如何在建站主机中优化服务器配置?
如何在阿里云虚拟主机上快速搭建个人网站?
网站建设要注意的标准 促进网站用户好感度!
javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】
如何在Windows服务器上快速搭建网站?
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
微信h5制作网站有哪些,免费微信H5页面制作工具?
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
Android使用GridView实现日历的简单功能
如何正确下载安装西数主机建站助手?
奇安信“盘古石”团队突破 iOS 26.1 提权
如何快速查询域名建站关键信息?
HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
如何在服务器上配置二级域名建站?
Laravel如何使用查询构建器?(Query Builder高级用法)
iOS发送验证码倒计时应用
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
大连 网站制作,大连天途有线官网?
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
微信小程序 五星评分(包括半颗星评分)实例代码
Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境
PythonWeb开发入门教程_Flask快速构建Web应用

