java序列化和反序列化

一、什么是对象序列化和对象反序列化?
 序列化:把java对象转换为字节序列的过程。
 反序列化:把字节序列恢复为java对象的过程。

 

二、使用场景、用途
 1.持久化对象,保存对象的字节序列到本地文件中。
 2.通过序列化对象在网络中传递数据。
 3.通过序列化对象在进程间传递数据。
 4.通过序列化对象实现分布式对象。例如RMI要利用对象序列化运行远程主机上的服务,与在本地主机上运行对象相同。


三、实现对象序列化的方法
 1.实现Serializable接口,系统默认实现序列化。
 2.实现Externalizable接口,需要自己定义序列化和反序列化过程,即实现接口中的readExternal()和writeExternal()方法。 


四、如何实现对象在磁盘上的存取操作?
        可以通过ObjectOutputStream中的writeObject(Object obj)和ObjectInputStream中的readObject(Object obj)来完成。
注意:以对象为单位进行文件写入时,该对象类型必须是可序列化的,否则会抛出NotSerializableException异常。


五、使用ObjectInputStream读取对象时为什么会发生StreamCorruptedException异常?
       StreamCorruptedException是流中的控制信息不一致异常,当从对象流中读取的控制信息与内部一致性检查相冲突时,就会抛出此异常。
       由于Serializable序列化机制实现时要求ObjectOutputStream对象和ObjectInputStream对象一一对应,即一个ObjectOutputStream对象输出的对象要使用一个ObjectInputStream对象读入。


六、对象中的成员哪些参与序列化?哪些不参与序列化?
1.参与序列化:属性,包括基本数据类型、数组以及其他对象的引用;类名。
2.不参与序列化:方法;static属性;transient属性。



七、如何自定义序列化和反序列化过程?
1.使用Serializable接口时,重写writeObject(ObjectOutputStream out)和readObject(ObjectInputStream in)方法;

注意:对于简单类型的属性,必须使用默认的writeInt(int i)、readInt(int i)等方法进行读写操作,而对于引用类型的属性,可以在writeObject(ObjectOutputStream out)和readObject(ObjectInputStream in)方法中使用writeObject()和readObject()进行读写。

另外,在文件或网络中读取属性时,读取顺序必须和写入顺序一致。

2.使用Externalizable接口时,重写接口中的readExternal()和writeExternal()方法。


八、在序列化类中添加serialVersionUID有什么作用?
        如果没有显示定义serialVersionUID,那么编译时会自动生成一个serialVersionUID,而每次编译会生成不同的serialVersionUID,在反序列化对象
过程中会对serialVersionUID作比较,如果不相同就会发生InvalidClassException异常。
       如果不希望通过编译来强制划分软件版本,即保证实现序列化接口的类能兼容以前版本,只需要显示定义一个serialVersionUID,但是这不是必要的。


九、当序列化遭遇继承时,如何正确处理对象序列化过程?
1.如果父类实现了Serializable接口或Externalizable接口,则其所有子类自动实现序列化。
注意:在实际操作中,如果只需要对子类进行序列化,直接将其父类实现序列化是不可取的,因为这样会强制所有子类具有序列化的能力。
  
2.如果父类没有实现序列化,而子类实现了序列化,此时在序列化过程中会抛出InvalidClassException异常。正确做法是为父类提供无参构造方法,并且在子类中显示定义序列化和反序列化过程。


十、常见的序列化协议有哪些?
  xml,json,protobuf,Thrift和Avro


十一、序列化协议选型建议
1、对于公司间的系统调用,如果性能要求在100ms以上的服务,基于XML的SOAP协议是一个值得考虑的方案。 
2、基于Web browser的Ajax,以及Mobile app与服务端之间的通讯,JSON协议是首选。对于性能要求不太高,或者以动态类型语言为主,或者传输数据载荷很小的的运用场景,JSON也是非常不错的选择。 
3、对于调试环境比较恶劣的场景,采用JSON或XML能够极大的提高调试效率,降低系统开发成本。 
4、当对性能和简洁性有极高要求的场景,Protobuf,Thrift,Avro之间具有一定的竞争关系。 
5、对于T级别的数据的持久化应用场景,Protobuf和Avro是首要选择。如果持久化后的数据存储在Hadoop子项目里,Avro会是更好的选择。 
6、由于Avro的设计理念偏向于动态类型语言,对于动态语言为主的应用场景,Avro是更好的选择。 
7、对于持久层非Hadoop项目,以静态类型语言为主的应用场景,Protobuf会更符合静态类型语言工程师的开发习惯。 
8、如果需要提供一个完整的RPC解决方案,Thrift是一个好的选择。 
9、如果序列化之后需要支持不同的传输层协议,或者需要跨防火墙访问的高性能场景,Protobuf可以优先考虑。


参考资料:http://www.tuicool.com/articles/IVJFjiR



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值