本文是通过JDK源码对Java序列化和反序列化的一些总结和个人心得,和大家分享一下。
1.关于序列化和反序列化的定义
序列化:把Java对象转换为字节序列的过程称为对象的序列化
反序列化:把字节序列恢复为Java对象的过程称为对象的反序列化
最常用的序列化和反序列化的情形是在硬盘上存储和读取对象。
2.使用序列化和反序列化的原因
在JVM启动的情况下,用户可以创建自定义的对象,但是当虚拟机结束的时候,用户创建的对象也随之消失,考虑到对象的生命周期有限,而用户又想保存当前对象的状态,序列化和反序列化就是用来处理此种情况。
3.JDK对序列化和反序列化的支持
可序列化的类都必须实现java.io.Serializable。Java规定:未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。以下是JDK中对Serializable接口的定义。
public interface Serializable {
}
对可序列化的对象的处理是通过java.io.ObjectOutputStream和java.io.ObjectInputStream类特殊处理的。
4.通过以下实例来简单介绍序列化的相关使用:
import java.io.Serializable;
public class Person implements Serializable {
String nameString;
int age;
public String getNameString() {
return nameString;
}
public void setNameString(String nameString) {
this.nameString = nameString;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void print(){
System.out.println("name : "+ nameString+" , age : "+age);
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class TestSerializable {
public static void main(String[] args) {
// TODO Auto-generated method stub
ObjectOutputStream personObjectOutputStream =null;
ObjectInputStream personObjectInputStream = null;
//序列化对象
try {
//1.创建对象输出流
personObjectOutputStream= new ObjectOutputStream(new FileOutputStream("c:/person.txt"));
//2.创建要输出的对象
Person person = new Person();
person.setAge(10);
person.setNameString("tianxingzhe");
//3.写入对象
personObjectOutputStream.writeObject(person);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//4.关闭对象
if(personObjectOutputStream != null){
try {
personObjectOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
try {
//1.创建输入对象流
personObjectInputStream = new ObjectInputStream(new FileInputStream("c:/person.txt"));
//2.写入对象
Person person = (Person)personObjectInputStream.readObject();
person.print();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//3.关闭写入对象流
if(personObjectInputStream != null){
try {
personObjectInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
在序列化和反序列化过程中需要特殊处理的类必须使用下列方法来实现特殊方法
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
5.使用序列化和反序列化时需要注意的事项:
- 可序列化类的所有子类型本身都是可序列化的
- 可序列化的子类必须能够访问父类无参数的构造方法
- 当某个字段被声明为transient后,默认序列化机制就会忽略该字段