Java 序列化深入分析Word文档下载推荐.docx

上传人:b****5 文档编号:15686650 上传时间:2022-11-15 格式:DOCX 页数:13 大小:19.34KB
下载 相关 举报
Java 序列化深入分析Word文档下载推荐.docx_第1页
第1页 / 共13页
Java 序列化深入分析Word文档下载推荐.docx_第2页
第2页 / 共13页
Java 序列化深入分析Word文档下载推荐.docx_第3页
第3页 / 共13页
Java 序列化深入分析Word文档下载推荐.docx_第4页
第4页 / 共13页
Java 序列化深入分析Word文档下载推荐.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

Java 序列化深入分析Word文档下载推荐.docx

《Java 序列化深入分析Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Java 序列化深入分析Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。

Java 序列化深入分析Word文档下载推荐.docx

Serializable接口

  Serializable接口在JDK源码中定义如下:

/*

*@authorunascribed

*@seejava.io.ObjectOutputStream

*@seejava.io.ObjectInputStream

*@seejava.io.ObjectOutput

*@seejava.io.ObjectInput

*@seejava.io.Externalizable

*@sinceJDK1.1

*/

publicinterfaceSerializable{

}

  Java从JDK1.1开始支持对象的序列化机制,有上图的源码可知,Serializable接口没有声明任何方法,实现该接口的Java类不需要对任何方法提供实现(默认情况下,定制序列化时除外),**因此,该接口仅仅是一个markinterface(标记接口)”,实现该接口意味着告知JVM该对象可以序列化。

**Java序列化机制要求所有具备序列化的对象必须实现该接口,否则是不能被序列化的,如果对于没有实现该接口的对象进行序列化时,JavaAPI会抛出异常,无法进行序列化。

transient关键字

  瞬时变量,指的是被transient关键字修饰的变量,该关键字表示为瞬时的,即不做持久化处理的,以此来控制属性是否被包含进入序列化的字节流中。

  Serializable接口提供了默认的序列化行为,在默认情况下,开发人员只需实现该接口,无需进行其他额外的操作,即可实现的对象的序列化。

默认只对对象中非静态的字段以及非瞬时的字段进行序列化,其他的字段是不允许被序列化的。

  这是因为,静态变量是类变量,属于整个类,并非专属于每个对象实例,因此,不序列化静态变量时合理的。

瞬时变量,指的是被transient关键字修饰的变量,该关键字表示为瞬时的,即不做持久化处理的,以此来控制属性是否被包含进入序列化的字节流中。

因此,在序列化时,排除transient关键字修饰的属性也是合理的。

  这种情况的具体表现就是,在序列化的有序字节流中没有保存不能被序列化的字段的状态,因此,在反序列化时,这些字段状态是不能被重建的。

但是有一点需要注意的是,经过反序列化后的对象,除了对可被序列化的字段状态进行重建之外,其他的没有被序列化的字段作为对象属性的一部分,也在对象重建时得以初始化。

但是这些字段的状态是不被保存的,重建后的这些属性仅仅是系统赋予的默认值,而非保存了对象序列化之前的状态。

实现Serializable接口除了提供默认的序列化方式之外,同样允许开发人员定制序列化,即通过实现以下相同签名的方法来实现:

序列化方法:

privatevoidwriteObject(java.io.ObjectOutputStreamout)throwsIOException

反序列化方法:

privatevoidreadObject(java.io.ObjectInputStreamin)throwsIOException,ClassNotFoundException;

其中,writeObject方法用于定制序列化,readObject方法用于实现定制反序列化。

serialVersionUID

  每个实现Serializable接口的对象都有一个serialVersionUID,长整型,64位,唯一标示了该序列化对象。

在类定义中,可以显示的定义该静态变量,也可以不定义。

在不定义的情况下,Java编译器会隐式的生成该变量。

强烈建议显示定义。

那么,该变量有什么用途呢?

反序列化兼容控制,serialVersionUID相同才能进行反序列化。

例如:

远程主机需要反序列化对象C,如果在本地和远程主机内的C对象持有的serialVersionUID不同,即使两个类其它部分完全一样,也是不能成功反序列化话的,会抛出异常。

因此,如果对类做了修改,为了保证版本对序列化兼容,该变量的值保持不变。

从另一个角度来讲,不期望不同版本的类对序列化兼容,则改变该变量值。

序列化保存的数据

  那么,到底哪些数据被序列化到了有序字节流中呢?

字节流数据包含了non-static和non-transient类型的成员数据、类名、类签名、可序列化的基类以及类中引用的其他对象。

针对于父类,有几点原则:

1.如果基类实现了Serializable接口,则其子类默认的是可序列化的,不必显示声明;

2.如果基类没有实现Serializable接口,在反序列化时,会调用基类的无参构造方法来重建基类对象,只不过不会保留基类对象状态。

利用Serializable实现序列化的实例。

publicclassUserimplementsSerializable{

privateStringuserName;

privateStringpassWord;

publicUser(StringuserName,StringpassWord){

this.userName=userName;

this.passWord=passWord;

}

publicStringgetUserName(){

returnuserName;

publicvoidsetUserName(StringuserName){

publicStringgetPassWord(){

returnpassWord;

publicvoidsetPassWord(StringpassWord){

@Override

publicStringtoString(){

return"

User{"

+

"

userName='

"

+userName+'

\'

'

passWord='

+passWord+'

'

}'

;

测试代码

importjava.io.*;

/**

*@authorbridge

publicclassClient{

publicstaticvoidmain(String[]args){

//构造一个可以序列化对象

Useruser=newUser("

Bridge"

"

123456"

);

//执行序列化

try{

ObjectOutputStreamout=newObjectOutputStream(

newFileOutputStream("

User.dat"

));

out.writeObject(user);

}catch(IOExceptione){

e.printStackTrace();

//反序列化

ObjectInputStreamin=newObjectInputStream(

newFileInputStream("

UseruserRecover=(User)in.readObject();

System.out.println(userRecover);

}catch(ClassNotFoundExceptione){

运行结果

User{userName='

Bridge'

123456'

Externalizable接口

Externalizable接口继承成自Serializable接口,实现该接口意味着对象本身完全掌控自己的序列化方式。

该接口JDK源码如下:

publicinterfaceExternalizableextendsjava.io.Serializable{

voidwriteExternal(ObjectOutputout)throwsIOException;

voidreadExternal(ObjectInputin)throwsIOException,ClassNotFoundException;

Externalizable接口定义了两个方法:

writeExternal(ObjectOutputout)和readExternal(ObjectInputin)。

write方法用于实现定制序列化,read方法用于实现定制反序列化,

定制序列化

  大部分情况下,我们期望对类似于密码等这样的敏感信息进行加密处理,以密文的形式在网络间传输,增强数据的安全性。

但是,通过我们上述的方式进行序列化,默认的处理方式是不能保证密码的密文传输的。

因此,针对此类问题,我们必须能够定制对象的序列化和反序列化过程,只有这样才能将我们的业务逻辑加入其中,以满足实际应用的需要。

基于Serializable接口的定制

  定制序列化和反序列化与上述序列化方式的不同在于:

自定义类的实现。

首先,同样,自定义的类要实现Serializable接口,这是序列化处理的前提。

不同的是,在定制序列化时,需要根据我们的实际需要,重写writeObject和readObject方法,完成序列化和反序列化的定制。

示例代码如下:

User.java

importsun.misc.BASE64Decoder;

importsun.misc.BASE64Encoder;

privatevoidwriteObject(ObjectOutputStreamout)throwsIOException{

ObjectOutputStream.PutFieldputField=out.put

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1