java自定义序列化的具体使用
作者:写不完作业还要玩 发布时间:2022-02-06 06:27:12
目录
1.问题引出
2.解决办法
3.另外一种自定义序列化机制(介绍Externalizable)
1.问题引出
在某些情况下,我们可能不想对于一个对象的所有field进行序列化,例如我们银行信息中的设计账户信息的field,我们不需要进行序列化,或者有些field本省就没有实现Serializable接口。
java中的序列化是递归序列化,也就是你的field的引用类型中也有field可以被序列化,那么就会在序列化当前对象的时候,一同序列化
2.解决办法
使用transient(瞬变现象;过往旅客;候鸟)关键字来修饰,该关键字只能修饰属性,这样在序列化的时候,这个属性就会用默认值,例如int类型用0,引用对象用null;
但是使用transient关键字修饰的field虽然简单方便,但是会被完全隔离在序列化机制之外,这样导致在反序列化回复java对象的时候,无法取得该field的值。
因此我们可以使用自定义序列化机制,可以让程序控制如何序列化各field,甚至完全不序列化某些field(这样就与transient相同),在序列化和反序列化过程中需要特殊处理的类应该提供如下特殊签名的方法,这些特殊的方法用以实现自定义的序列化
private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in)throws IOException,ClassNotFoundException;
private void readObejctNoData()throws ObejctStreamException;
热爱你所写的每一行的代码
writeObject()方法负责写入特定类的实例状态,通过重写这个方法,程序员可以完全获得对序列化机制的控制,可以自主决定那些field需要序列化,需要怎么序列化,默认情况(函数体为空)该方法会调用out.defaultWriteObject来保存java对象的各field,从而达到实现序列化java对象状态的目的
readObject负责从流中读取并且回复对象的field,通过重写该方法,程序员,可以获得对反序列化机制的控制,对于反序列化各个field的顺序应该和序列化各个field的顺序相同。
至于当序列化流不完整时,readObjectNoData可以正确的初始化反序列化的对象,例如接收方接收到的序列化流残缺,或者序列化版本不同,则使用readObjectNoData来默认的初始化。
例子(对于person的改写):
class Person implements Serializable
{
private String name;
private int age;
public Person(String name,int age)
{
this.name=name;
this.age=age;
}
//自动生成的Get和Set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void writeObject(ObjectOutputStream out) throws IOException
{
//将名字翻转之后写入二进制流
out.writeObject(new StringBuffer(this.name).reverse());
out.writeInt(this.age);
}
private void readObject(ObjectInputStream in)throws IOException,ClassNotFoundException
{
this.name=((StringBuffer)in.readObject()).reverse().toString();
//会抛出异常,因为这里的这样写法导致同
this.age=in.readInt();
}
}
应该提醒的是,这个自定义的功能十分强大
另外一种替换性的改写:
//注意:这个方法由序列化机制调用,只要该方法存在就,它的访问控制符就可以为private protected package-private中的任意一种
private Object writeReplace() throws ObjectStreamException
{
ArrayList<Object> list=new ArrayList<>();
list.add(name);
list.add(age);
//我们这里返回ArrayList
return list;
}
序列化机制保证在序列化某个对象之前,先调用该对象的writeReplace方法,如果该方法返回另外一个java对象,系统就转换为序列化writeReplace的返回结果。(ps:如果这个返回结果也有writeReplace方法的话,就继续递归替代,直到没有替换)
相应与writeReplace相对的有一个readResolve方法,这个方法保护性的赋值整个对象,这里就不展开讨论了。
3.另外一种自定义序列化机制(介绍Externalizable)
Java还提供了另一种序列化机制,这种序列化方式完全由程序员决定存储和恢复对象数据。要实现该目标,Java类必须实现Externalizable接口,该接口里定义了如下两个方法。
void readExternal(ObjectInput in):需要序列化的类实现readExternal()方法来实现反序列化。该方法调用DataInput(它是ObjectInput的父接口)的方法来恢复基本类型的Field值,调用ObjectInput的readObject()方法来恢复引用类型的Field值。
void writeExternal(ObjectOutput out):需要序列化的类实现writeExternal()方法来保存对象的状态。该方法调用DataOutput(它是ObjectOutput的父接口)的方法来保存基本类型的Field值,调用ObjectOutput的writeObject()方法来保存引用类型的Field值。
具体的实现方式与上面自定义Serializable接口的实现类的序列化是相同的操作,这里就不阐述了,下面图是二者的比较。
来源:https://www.cnblogs.com/oldoldcoder/p/15555198.html
猜你喜欢
- 1.前提:已安装JDK14,可以到jdk官网下载,或加QQ群835259695,快速免费下载2.不说没用的直接上jdk14环境下的jpack
- 由于我们在eclipse ee中把项目部署在web端经常会出现报404错误。原因为:404状态码是一种http状态码,其意思是: 所请求的页
- 最近要做一个java web项目,因为页面不是很多,所以就没有前后端分离,前后端写在一起,这时候就用到thymeleaf了,以下是不动脑式的
- 说到人脸检测,首先要了解Haar特征分类器。Haar特征分类器说白了就是一个个的xml文件,不同的xml里面描述人体各个部位的特征值,比如人
- 序列化和反序列化Java是面向对象的语言,与其他语言进行交互(比如与前端js进行http通信),需要把对象转化成一种通用的格式比如json(
- MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoD
- 今天一个读者问我关于Android通过调用Webservice实现天气预报这篇文章的源码下载后出现的错误Could not find cla
- 本文介绍了Spring Security 控制授权的方法,分享给大家,具体如下:使用授权方法进行授权配置每一个 Spring Securit
- 准备:wildfly/tomcat或者其他服务器你的数据库的Driver,(此处用的mysql-connecter-java-5.1.39-
- mybatis的原身是ibatis,现在已经脱离了apache基金会,新官网是http://www.mybatis.org/。在研究Myba
- 1.启动项目的时候报错1.Error starting ApplicationContext. To display the auto-co
- 环境:VS2019+Qt5.121. CLR库安装 &nb
- 本文实例讲述了Android编程开发之TextView单击链接弹出Activity的方法。分享给大家供大家参考,具体如下:话不多说直接上码:
- 一、前言系统执行业务逻辑之前,会对输入数据进行校验,检测数据是否有效合法的。所以我们可能会写大量的if else等判断逻辑,特别是在不同方法
- java自定义切面增强写代码时会遇到一些有些重复机械的工作, 这个时候就可以运用切面技术来帮我们节约时间介绍如何使用自定义注解增强方法, 实
- 1.概念a.是个二叉树(每个节点最多有两个子节点)b.对于这棵树中的节点的节点值左子树中的所有节点值 < 根节点 < 右子树的所
- Struts2是流行和成熟的基于MVC设计模式的Web应用程序框架。 Struts2不只是Struts1下一个版本,它是一个完全重写的Str
- 前言最近在改进项目的并发功能,但开发起来磕磕碰碰的。看了好多资料,总算加深了认识。于是打算配合查看源代码,总结并发编程的原理。准备从用得最多
- 目录Spring自动注入失败如何解决?回答注入你的bean使用@Configurable手动查找bean:不推荐Spring自动注入失败如何
- 在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理