该接口的定义为:
public interface Serializable { }//大括号内为空。这是一种特殊的接口。
Java的"对象序列化"能让你将一个实现了Serializable接口的对象转换成byte流,这样日后要用这个对象时候,你就能把这些byte数据恢复出来,并据此重新构建那个对象了。
1.特点
1:当一个对象被序列化时,只保存对象的非静态成员变量(包括声明为private的变量),不能保存任何的成员方法和静态的成员变量。2:如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被序列化。
3:如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。
2.实现此接口
只需在自己的类上加上implements java.io.Serializable即可。IDE会提示你 *add default serial version ID*然后就完成了。**serialVersionUID**
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,InvalidCastException。
当一个类实现了Serializable接口而没有显示地定义serialVersionUID,Eclipse会提示你“The serializable class SplitSentence does not declare a static final serialVersionUID field of type long”。点击quick fixes available,eclipse会帮你实现下行语句:
private static final long serialVersionUID = 1L;
3.transient关键字
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。
4.例子
一个泛型函数:
/** * @param srcObject its class need to implement Serializable * */ @SuppressWarnings("unchecked") public static <T> T deepCopy(T srcObject) throws IOException, ClassNotFoundException{ ByteArrayOutputStream byteStream=new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(byteStream); oos.writeObject(srcObject); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream( byteStream.toByteArray())); return (T)ois.readObject(); }