Java基础(1) 序列化与反序列化
2016-10-11 16:57
281 查看
1. 概念
Java序列化是指把Java对象转换为字节序列的过程。Java反序列化是指把字节序列恢复为Java对象的过程。
使用场景:
内存中的对象保存到文件或数据库中
用Socket在网络上传送对象
通过RMI传输对象
2. 序列化的三种方式
仅实现Serializable接口的默认序列化实现Serializable接口,同时定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputStream out)
实现Externalnalizable接口,同时定义readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法
3. 默认序列化
3.1. 注意事项
默认序列化是深度拷贝,不仅仅是基本对象,对所有对象都会进行复制,而不是仅仅复制对象的引用。因为是深度拷贝,所以要求所有被序列化的对象都实现了序列化(递归检测),否则会抛出java.io.NotSerializableException异常。例外有,基本类型,基本类型的数组,枚举类型。
静态字段和transient修饰的字段默认情况下不会被序列化(自定义序列化时可以),在反序列化之后会被赋值为初始值(0,null)。
父类实现序列化,那子类也默认实现序列化。子类序列化时,默认会序列化父类内容。
父类没有实现序列化接口,子类实现了序列化接口。默认序列化时,父类成员不会进行序列化。同时,父类必须有无参数构造器。
3.2. 简单实例
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class AA implements Serializable{ /** * */ private static final long serialVersionUID = 6465468687825253519L; private int a; public AA() {} public AA(int a) { this.a = a; } public int getA() { return a; } public void setA(int a) { this.a = a; } @Override public String toString() { return "AA [a=" + a + "]"; } } public class SerializableTestTwo { public static void main(String[] args) throws Exception { //默认序列化 AA a = new AA(1); FileOutputStream fos = new FileOutputStream( new File("/Users/irving/Documents/serializable")); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(a); //默认反序列化 FileInputStream fis = new FileInputStream(new File("/Users/irving/Documents/serializable")); ObjectInputStream ois = new ObjectInputStream(fis); AA aa = (AA) ois.readObject(); System.out.println(aa.toString()); } }
3.3. 默认序列化的四个方法
writeReplace方法:与readResolve方法类似,可以用于控制单例对象writeObject方法
readObject方法
readResolve方法:控制单例对象
4. 自定义序列化
不熟悉 没找到什么有用的实例5. Externalnalizable接口序列化
当反序列化时,会先调用无参数构造器创建一个新的对象(Serializable接口后不会调用无参数构造器),然后再进行填充。所以使用这种方法时必须要有一个无参数构造器,且未public。适合用于深度序列化,writeExternal和readExternal方法是必须的
同时实现Serializable接口与Externalnalizable接口时,Serializable接口失效。
6. serialVersionUID
默认情况下JVM会自动生成,但强烈建议一开始就定义好,且不改变。各个JVM下相同类生成的UID不相同,且同一JVM下同一类修改后UID也会改变,所以最好一开始就指定,且不改变。
用途:
不同版本序列化兼容,则要求有相同的UID
不同版本序列化要求不兼容,则要求有不相同的UID
7. readResolve方法(effective java第77条)
对于一个正在被反序列化的对象,如果定义了readResolve方法,并且具备正确的声明,那么在反序列化之后,新建对象上的readResolve方法就会被调用,然后改方法返回对象的引用将被返回,取代新建对象。如果依赖readResolve方法进行实例控制,带有对象引用类型的所有实例域都必须声明为transient,否则
8. 序列化存在的问题
默认序列化形式会导致在类的公共API中泄漏私有字段。在Effective java中有很多,但没看懂
9. 资料
http://imxylz.blog.sohu.com/186773591.htmlhttp://www.2cto.com/kf/201405/305380.html
http://www.cnblogs.com/xiohao/p/4234184.html
相关文章推荐
- Java 基础----序列化
- JAVA序列化基础知识Serializable与Externalizable的区别
- Java基础之对象的序列化(持久化)操作对象ObjectInputStream/ObjectOutputStream
- Java基础——对象序列化
- java基础-序列化
- java基础学习---java对象序列化基础知识
- java培训:Java对象序列化使用基础
- java基础之 对象序列化、transient关键字、StringTokenizer
- 黑马程序员----JAVA基础之序列化与反序列化
- java基础之IO File类和序列化Object
- java基础问题---什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。
- Java对象序列化使用基础
- Java序列化基础事项回顾
- JAVA 基础之 序列化 Serializable
- Java基础知识之系统命令调用、序列化、JDO、匿名内部类
- java基础 序列化与反序列化
- JAVA序列化基础知识Serializable与Externalizable的区别(改变默认的序列化/反序列化行为)
- java基础之IO File类和序列化Object
- Java基础之数组序列化、反序列化 小发现(不知道 是不是有问题)
- Java基础之数组序列化、反序列化 小发现(不知道 是不是有问题)