Java中需要序列化的类,只需实现Serializable接口,具体的实现由虚拟机负责调用相关实现方式去实现。所有的non-transient和non-static都将被序列化。
class SessionDTO implements Serializable {
private static final long serialVersionUID = 1L;
private int data; // Stores session data
// Session activation time (creation, deserialization)
private long activationTime;
public SessionDTO(int data) {
this.data = data;
this.activationTime = System.currentTimeMillis();
}
public int getData() {
return data;
}
public long getActivationTime() {
return activationTime;
}
}
public class SerializeTester implements Serializable {
public static void main(String... strings) throws Exception {
File file = new File("out.ser");
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
SessionDTO dto = new SessionDTO(1);
oos.writeObject(dto);
oos.close();
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(file));
SessionDTO dto = (SessionDTO) ois.readObject();
System.out.println("data : " + dto.getData()
+ " activation time : " + dto.getActivationTime());
ois.close();
}
}
某些情况下,如果某些字段不需要进行序列化,可以将其设置为transient,这样这些字段就不会进行序列化,以减轻对网络带宽的占用。某些值,如果需要在反序列化的时候重新赋值,可以设置为transient,并且重写readObject方法,在其中为该属性赋值。如果希望序列化的时候对某些值做自定义的处理,可以重写writeObject方法,添加相应逻辑。
class SessionDTO implements Serializable {
private static final long serialVersionUID = 1L;
private transient int data; // Stores session data
//Session activation time (creation, deserialization)
private transient long activationTime;
public SessionDTO(int data) {
this.data = data;
this.activationTime = System.currentTimeMillis();
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeInt(data);
System.out.println("session serialized");
}
private void readObject(ObjectInputStream ois) throws IOException,
ClassNotFoundException {
ois.defaultReadObject();
data = ois.readInt();
activationTime = System.currentTimeMillis();
System.out.println("session deserialized");
}
public int getData() {
return data;
}
public long getActivationTime() {
return activationTime;
}
}
两个方法都是private的,并且它们既不存在于java.lang.Object,也没有在Serializable中声明。那么ObjectOutputStream如何使用它们的呢?这个吗,ObjectOutputStream使用了反射来寻找是否声明了这两个方法。因为ObjectOutputStream使用getPrivateMethod,所以这些方法不得不被声明为priate以至于供ObjectOutputStream来使用。