Java对象的序列化主要有两种用途:
- 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
- 在网络上传送对象的字节序列。
序列化接口与API
在Java中,只要一个类实现了java.io.Serializable接口(没有方法),那么它就可以被序列化。
对象序列化步骤:
- 创建一个对象输出流ObjectOutputStream,它可以包装一个其他类型的目标输出流,如文件输出流;
- 通过对象输出流的writeObject(obj)方法写对象。
对象反序列化步骤:
- 创建一个对象输入流ObjectInputStream,它可以包装一个其他类型的源输入流,如文件输入流;
- 通过对象输入流的readObject()方法读取对象。
父类对象序列化
要想将父类对象也序列化,就需要让父类也实现Serializable 接口
transient控制符
transient控制符表示该属性不参与序列化
关于静态变量
静态变量不会被序列化,因为所有的对象共享同一份静态变量的值
例子
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = -5809782578272943989L;
private int age;
private String name;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
// Test
public class MainTest {
public static void main(String[] args) {
byte[] buf = SerializePerson();
Person p = DeserializePerson(buf);
System.out.println(MessageFormat.format("name={0}, age={1}",
p.getName(), p.getAge()));
}
private static byte[] SerializePerson() {
Person person = new Person();
person.setName("suninf");
person.setAge(25);
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(person);
oos.close();
return os.toByteArray();
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
}
return null;
}
private static Person DeserializePerson(byte[] buf) {
Person person = null;
try {
InputStream is = new ByteArrayInputStream(buf);
ObjectInputStream ois = new ObjectInputStream(is);
person = (Person) ois.readObject();
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
} catch (ClassNotFoundException ex) {
}
return person;
}
}
serialVersionUID的作用
serialVersionUID 字面意思上是序列化的版本号,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量,版本不一致会抛出异常。
只要指定了serialVersionUID,就可以在序列化后,去添加一个字段,或者方法,而不会影响到后期的还原,还原后的对象照样可以使用。
自定义序列化行为
序列化类中包含writeObject 和 readObject 方法
要序列化的类,可以通过实现writeObject 和 readObject来自定义序列化的实现,在使用ObjectOutputStream的writeObject方法和ObjectInputStream的readObject方法时,会通过反射的方式调用。
比如,ArrayList<T>
就自定义实现了writeObject 和 readObject 方法。
Externalizable接口
- Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为
- 而仅实现Serializable接口的类可以采用默认的序列化方式