title: Java序列化
date: 2017-03-18 22:37:00
tags: java
什么是序列化?
Java序列化是指把Java对象转换为字节序列的过程;反序列化就是把字节序列再恢复成Java对象的过程
序列化的作用是什么?
一般序列化的作用有两方面:
- 把对象转换成字节序列永久的保存到硬盘上(保存到文件中),在MVC中很好用
- 在网络上传送对象的字节序列
简单的说,就是把数据(对象)换个时间或者是换个地方,继续使用
- 换个时间,比如说把数据存盘
- 换个地方,比如网络间数据的传输
网络间对象的传输
我们可以通过网络传输图片、文子、音像、视频等资料,同样也可以传对象,这样两个Java程序间通信就可以交换数据。(云服务,把用户数据从服务器传输给用户等)
如何实现序列化和反序列化?
一个不是很难理解的过程,很像是一个处理流
对象流:ObjectOutputStream和ObjectInputStream
ObjectOutputStream对象输出流,在实例化时new ObjectOutputStream(OutputStream os)
获取输出流,然后writeObject(Object obj)
方法可以对参数指定的obj对象进行序列化,然后可以把序列化的的字节序列写到这个os流中;
序列化操作
File file = new File(file_name);
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
// ......
Object obj = new Object();
oos.writeObject(obj);
// ......
反序列化操作
ObjectInputStream对象输出流,在实例化时new ObjectOutputStream(OutputStream os)
获取输入流,然后(Object)readObject()
方法可以把读取到的字节序列强制转换成某个类的对象,并赋值;
File file = new File(file_name);
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
// ......
// 所需的对象字节序列都在流中
Object obj = (Object)ois.readObject();
// ......
必备条件
只有实现了Serializable或Externalizable接口的类
的对象才能被序列化,否则会抛出异常
- 实现Serializable接口
使用默认的序列化/反序列化的方式,对类的非transient的实例对象进行序列化和反序列化 - 实现Serializable接口并重写了writeObjetct和readObject方法
该类对象就可以调用重写后的读写方法 - 实现Externalizable接口并重写了writeExternal和readExternal方法
该类对象可以调用读写方法 - 直接使用JDK类库
上述代码段的使用方式,不再赘述
注意
对象序列化写入到对象流中的顺序应该与读取对象反序列化时的顺序一致
对于transient关键字的补充
- transient只能修饰变量,不能修饰方法和类
- 被transient修饰的变量不能被序列化;同时,static静态变量不管是否被transient修饰,都不会被序列化
- 一旦变量被transient修饰,变量将不会被作为持久化对象中的一部分,该变量内容在序列化后不能被访问(变量还在,但变量中的值不在了)
日常总结
被虐了…直到现在还在心塞,原理还是不懂,这些Java的小细节可以说是知之甚少,虽然听说过,但怎么用,为什么这么用,实现的原理是什么,一句话都说不出来…
关键是还知道这是各种面试笔试都会被提到的高频知识点…讲真的,该去买书看了,JVM、设计模式…
PS:没错,我又开始挖坑了…剩下的慢慢写好了