谈谈J2SE中的序列化(二)
当序列化遇到继承…当一个父类实现Serializable接口后,他的子类都将自动的实现序列化。
以下验证了这一点:
package Serial;
import java.io.Serializable;
public class SuperC implements Serializable {//父类实现了序列化
int supervalue;
public SuperC(int supervalue) {
this.supervalue = supervalue;
}
public String toString() {
return "supervalue: "+supervalue;
}
}
public class SubC extends SuperC {//子类
int subvalue;
public SubC(int supervalue,int subvalue) {
super(supervalue);
this.subvalue=subvalue;
}
public String toString() {
return super.toString()+" sub: "+subvalue;
}
}
public class Test1 {
public static void main(String [] args){
SubC subc=new SubC(100,200);
FileInputStream in=null;
FileOutputStream out=null;
ObjectInputStream oin=null;
ObjectOutputStream oout=null;
try {
out = new FileOutputStream("Test1.txt");//子类序列化
oout = new ObjectOutputStream(out);
oout.writeObject(subc);
oout.close();
oout=null;
in = new FileInputStream("Test1.txt");
oin = new ObjectInputStream(in);
SubC subc2=(SubC)oin.readObject();//子类反序列化
System.out.println(subc2);
} catch (Exception ex){
ex.printStackTrace();
} finally{
…此处省略
}
}
}
运行结果如下:
supervalue: 100 sub: 200
可见子类成功的序列化/反序列化了。
怎管让子类实现序列化看起来是一件很简单的事情,但有的时候,往往我们不能够让父类实现Serializable接口,原因是有时候父类是抽象的(这并没有关系),并且父类不能够强制每个子类都拥有序列化的能力。换句话说父类设计的目的仅仅是为了被继承。
要为一个没有实现Serializable接口的父类,编写一个能够序列化的子类是一件很麻烦的事情。java docs中提到:
“To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype@#s public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class@#s state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime. ”
也就是说,要为一个没有实现Serializable接口的父类,编写一个能够序列化的子类要做两件事情:
其一,父类要有一个无参的constructor;
其二,子类要负责序列化(反序列化)父类的域。
我们将SuperC的Serializable接口去掉,而给SubC加上Serializable接口。运行后产生错误:
java.lang.Error: Unresolved compilation problem:
Serializable cannot be resolved or is not a valid superinterface
at Serial.SubC.<init>(SubC.java:15)
at Serial.Test1.main(Test1.java:19)
Exception in thread "main"
果真如docs中所说的一样,父类缺少无参构造函数是不行的。
接下来,按照docs中的建议我们改写这个例子:
public abstract class SuperC {
int supervalue;
public SuperC(int supervalue) {
this.supervalue = supervalue;
}
public SuperC(){}//增加一个无参的constructor
public String toString() {
return "supervalue: "+supervalue;
}
}
public class SubC extends SuperC implements Serializable {
int subvalue;
public SubC(int supervalue,int subvalue) {
super(supervalue);
this.subvalue=subvalue;
}
public String toString() {
return super.toString()+" sub: "+subvalue;
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException{
out.defaultWriteObject();//先序列化对象
out.writeInt(supervalue);//再序列化父类的域
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
in.defaultReadObject();//先反序列化对象
supervalue=in.readInt();//再反序列化父类的域
}
}
运行结果证明了这种方法是正确的。在此处我们用到了writeObject/ readObject方法,这对方法如果存在的话,序列化时就会被调用,以代替默认的行为(以后还要探讨,先了解这么多)。我们在序列化时,首先调用了ObjectOutputStream的defaultWriteObject,它使用默认的序列化行为,然后序列化父类的域;反序列化的时候也一样。
归纳一下:
目的
行为
为一个实现Serializable接口的父类,编写一个能够序列化的子类
子类将自动的实现序列化
为一个没有实现Serializable接口的父类,编写一个能够序列化的子类
1, 父类要有一个无参的constructor;
2, 子类要先序列化自身,然后子类要负责序列化父类的域
下一篇:J2EE初学者需要理解的问题
↓相关文章:
- · J2EE初学者需要理解的问题
- · J2EE deployment files(web.xml)
- · J2EE deployment files (ejb-jar.xml)
- · j2sdk 与 Tomcat5配置方法与注意事项
- · J2ME学习笔记(七)
- · 开发J2EE应用应遵循的几点原则
- · [J2EE]项目艰辛笔记
- · J2EE程序中使用oracle数据库LOB字段的总结(elathen)
- · J2EE编程起步(一)
- · 走向J2EE,漫长的道路
- · [J2SE 5.0专题][3]虚拟机
- · J2EE clustering 1---有些老了
- · [J2SE 5.0专题][2.7]注解
- · [J2SE 5.0专题][2.1]泛型
- · J2EE 探险者:持久数据管理,第 2 部分
- · J2EE 探索者:使用 Java Servlets 2.4 来执行过滤
- · J2EE 探险者:持久数据管理,第 2 部分
- · 用J2EE开发N层应用
- · Oracle9iAS Containers for J2EE独立版指南--(部署servlet和JSP的方法)
- · Oracle9iAS Containers for J2EE独立版指南--(简介、安装、启动、关闭和帮助)
- · J2EE项目10大风险
- · J2EE全面介绍(一)
- · J2EE设计模式:CMP到BMP模式(一)
- · Spring Framework标记库初学指南
- · j2ee程序员应该掌握的linux知识
- · J2ME打包--解决移动平台api 问题
- · J2EE平台介绍
- · 应用Rational工具简化基于J2EE项目(五)架构与设计
- · 应用Rational 工具简化基于J2EE的项目 (三)转换到系统模型
- · 应用Rational 工具简化基于J2EE的项目(一)
- · 试析J2EE与.NET时代的商业利润
- · 应用OSCache提升J2EE系统运行性能
- · J2EE and XML Development -Ebook download
- · J2EE应用中与Oracle数据库的连接
- · 应用OSCache提升J2EE系统运行性能
- · j2EE基础概念(总结)
- · J2EE中的不同数据库之间事务(续)
- · J2SE 1.4 中assertion 功能介绍
- · J2EE学习笔记(4) 软件工程与系统框架
- · J2EE学习笔记(2) javascript 讨论
- · J2EE之类的概念
- · Charset in J2EE Web Application
- · EJB技术及应用
- · J2EE应用部署(三):高级篇
- · 了解Struts1.1介绍

