【Java】Serializable 接口
本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4356840.html
参考资料:
http://xiebh.iteye.com/blog/121311
http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html
http://www.cnblogs.com/vicenteforever/articles/1471775.html
http://blog.csdn.net/kkdelta/article/details/3958930
一、定义
Serializable(序列化)是 Java 提供的一种保存对象状态的机制。实现序列化接口后,类的实例可以通过输入输出流保存或读取当前的状态(即对象当前成员变量的值)。
二、使用场合
1. 将对象的状态保存到文件或数据库中时
2. 在网络上通过套接字传输对象时
3. 通过 RMI(RemoteMethodInvocation,远程方法调用)传输对象时
三、序列化实现示例
import java.io.*;
public class Box implements Serializable
{
private int width;
private int height;
public void setWidth(int width){
this.width = width;
}
public void setHeight(int height){
this.height = height;
}
public static void main(String[] args){
Box myBox = new Box();
myBox.setWidth(50);
myBox.setHeight(30);
try{
FileOutputStream fs = new FileOutputStream("foo.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(myBox);
os.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
四、注意事项
1. 序列化只能保存对象的非静态成员变量,不能保存任何成员方法和静态成员变量,而且序列化保存的只是变量的值,对于变量的任何修饰符都不能保存。
本人博客地址,防止无脑抄袭,影响阅读见谅:http://www.cnblogs.com/dbylk
2. transient 关键字
需要序列化的类中可能会包含某些无法恢复状态的变量或者不希望被序列化的变量,此时我们可以通过 transient 关键字标明这些变量。比如一个 Thread 对象或一个 FileInputStream 对象,即使保存了状态也无法为它们重新分配资源,此时必须使用 transient 关键字标明,否则编译器会报错;又比如需要在网络上发送一个对象时,某些需要保密字段会面临安全问题,我们不希望它们与其他数据一起被发送,此时可以通过 transient 关键字保证该字段不会被序列化,达到保密的目的。
3. serialVersionUID
serialVersionUID 被用来验证类的版本一致性。进行反序列化时,JVM 会比较字节流中的 serialVersionUID 与本地类型的 serialVersionUID,如果相同,则认为字节流中的对象与本地对象是一致的,可以进行反序列化,否则会抛出序列化版本不一致的异常(InvalidCastException)。serialVersionUID有两种显示的生成方式:一种是默认的1L,比如:private static final long serialVersionUID = 1L;一种是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段。点击 Eclipse 的warning 图标即可看到两种生成方式。如果不想定义它,可以在在Eclipse的设置把它关掉的,设置如下:Window -> Preferences -> Java -> Compiler -> Error/Warnings -> Potential programming problems 将 Serializable class without serialVersionUID 的 warning 改成 ignore 即可(不建议关闭,因为定义该值后可以避免反序列化时 JVM 对它的计算,可以带来小幅的性能提升)。
4. 当一个父类实现序列化时,子类自动实现序列化。
5. 当一个对象的实例变量为其他对象的引用时,序列化该对象的同时,它的引用对象也会被序列化。