JAVA从入门到精通:面试之Java序列化
小职 2017-10-10 来源 :网络 阅读 703 评论 0

摘要:本篇Java从入门到精通教程将会大家讲解Java编程这一知识点,看完这篇文章会让你对Java编程的知识点有更加清晰的理解和运用。

本篇Java从入门到精通教程将会大家讲解Java编程这一知识点,看完这篇文章会让你对Java编程的知识点有更加清晰的理解和运用。

序列化作用:

序列化将对象编码成字节流,主要用于对象的持久化,远程通信,跨进程访问等地方。

java中的序列化机制能够将一个实例对象(只序列化对象的属性值,而不会去序列化什么所谓的方法。)的状态信息写入到一个字节流中使其可以通过socket进行传输、或者持久化到存储数据库或文件系统中;然后在需要的时候通过字节流中的信息来重构一个相同的对象。

 

对象序列化:就是将Obj转换成byte序列;

{

并不是所有对象都需要实例化;

java中关键字transient:该元素不会进行jvm默认的序列化;

不会并不代表不能实例化;

1:wirteObject(ObjectOutputStream stream) throws IO{};

2:stream.defauleWriteObject();把jvm默认序列化的元素进行序列化操作;

3:可以调用stream.writeXxx():进行序列化;

反序列化:

1:readObject(ObjectInputStream s)throws{}

2:s.defaultReadObject();把jvm默认反序列化的元素进行反序列化操作;

3:s.readXxx();

}

 

注意事项

1.父类实现了序列化,则子类自动实现了序列化,即子类不需要显式实现Serializable接口,子类构造时会递归调用父类构造。

2.当父类没有实现序列化,而子类需要实现时,子类需要显式实现Serializable接口,并且父类中需要有无参的构造函数。

3.序列化只对对象的属性进行保存,而不会保存其方法。

4.当类中的实例变量引用了其他对象,那么在对该类进行序列化时,引用的对象也会被序列化。

 

1.Serializable接口:

Serializable接口是Java提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用Serializable来实现的对象的序列化相当简单,只需要在类的生命中指定一个类似相面的标识即可自动实现默认的序列化过程;

 

这种方式是Java提供的一种序列化方式,过程非常简单,甚至有些开发人员都不需要声明serialVersionUID也可以完成这个过程,但serialVersionUID到底需不需要指定呢?

需要!

Java API既然提供了这个serialVersionUID,那么它必定是有用的。这个serialVersionUID是用来辅助序列化和反序列化过程的,原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常地被反序列化。

serialVersionUID的详细工作过程是这样的:序列化的时候系统会把当前类的serialVersionUID写入序列化的二进制文件中,当反序列化的时候系统会检测文件中的serialVersionUID是否和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化;否则说明当前类和反序列化的类相比发生了某些变化,比如成员变量的数量、类型发生了变化,这个时候是无法正常反序列化的。

一般来说,我们应该手动指定serialVersionUID的值,比如1L,也可以让IDE根据当前类的结构自动去生成它的hash值,这样序列化和反序列化时两者的serialVersionUID是相同的,因此可以正常进行反序列化操作。如果不手动指定serialVersionUID的值反序列化时当前类有些改变,比如增加或者删除了某些成员变量,那么系统就会重新计算当前类的hash值并把它赋值给serialVersionUID,这个时候当前类的serialVersionUID就和反序列化数据中的serialVersionUID不一致,就会造成反序列化失败的结果。所以,手动指定serialVersionUID可以在很大程度上避免反序列化过程的失败。比如当版本升级后,我们可能删除了某个成员变量也可能增加了一些新的成员变量,这个时候我们的反序列化过程依然能够成功,程序仍然能够最大限度地回复数据;相反,如果不指定serialVersionUID的话,程序会发生Crash。

当然,我们还需要考虑一种情况,如果类结构发生了非城规改变,比如修改了类名,修改了成员变量的类型,这个时候尽管serialVersionUID验证通过了,但是反序列化过程仍然会失败,因为类的结构有了毁灭性的改变,根本无法从老版本的数据中还原出一个新的类结构的对象。

对于使用序列化还有两点需要注意:

1.静态成员变量属于类不属于对象,所以不参与序列化过程

2.用transient关键字标记的成员变量不参与序列化过程

2.Parcelable接口

Parcelable接口是Android SDK提供的一种专门用于Android应用中对象的序列化和反序列化的方式,相比于Seriablizable具有更好的性能。实现Parcelable接口的对象就可以实现序列化并可以通过Intent和Binder传递。

下面是一个完成的实现了Parcelable接口的类

public class User implements Parcelable{ public int userId; public String userName; public String password; public Book book; public User(int userId,String userName,String password,Book book){ this.userId=userId; this.userName=userName; this.password=password; this.book=book; } public int describeContents(){ //几乎所有情况都返回0,仅在当前对象中存在文件描述符时返回1 return 0; } public void writeToParcel(Parcel out,int flags){ out.writeInt(userId); out.writeString(userName); out.writeString(password); out.writeParcelable(book,0); } public static final Parcelable.Creator CREATOR=new Parcelable.Creator(){ public User createFromParcel(Parcel in){ return new User(in); } public User[] newArray(int size){ return new User[size]; } } private User(Parcel in){ userId=in.readInt(); userName=in.readString(); password=in.readString(); book=in.readParcelable(Thread.currentThread().getContextClassLoader()); }}41

 

看起来比Serializable方式复杂太多。我们使用表格把Parcelable方式的相关方法进行说明

方法 功能 标记位

createFromParcel(Parcel in) 从序列化后的对象中创建原始对象  

newArray(int size) 创建指定长度的原始对象数组  

User(Parcel in) 从序列化后的对象中创建原始对象  

writeToParcel(Parcel out,int flags) 将当前对象写入序列化结构中 PARCALABLE_WRITE_RETURN_VALUE

describeContents 返回当前对象的内容描述,几乎所有情况都返回0,仅在当前对象中存在文件描述符时返回1 CONTENTS_FILE_DESCRIPTOR

既然Parcelable和Serializable都可以实现序列化并且可以用于Intent间的数据传递,那么两者有什么区别呢?

区别 Serializable Parcelable

所属API JAVA API Android SDK API

原理 序列化和反序列化过程需要大量的I/O操作 序列化和反序列化过程不需要大量的I/O操作

开销 开销大 开销小

效率 低 很高

使用场景 序列化到本地或者通过网络传输 内存序列化


本文由职坐标整理并发布,希望对同学们学习Java的知识有所帮助。了解更多详情请关注职坐标Java频道!

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程