比较java.io.Externalizable和java.io.Serializable
来源:互联网 发布:白金数据1080p百度云 编辑:程序博客网 时间:2024/05/19 21:16
即使你没有用过对象序列化(serialization),你可能也知道它。但你是否知道 Java 还支持另外一种形式的对象持久化,外部化(externalization)?
下面是序列化和外部化在代码级的关联方式:
public interface Serializable {}
public interface Externalizable extends Serializable {
void readExternal(ObjectInput in);
void writeExternal(ObjectOutput out);
}
序列化和外部化的主要区别
外部化和序列化是实现同一目标的两种不同方法。下面让我们分析一下序列化和外部化之间的主要区别。
通过Serializable接口对对象序列化的支持是内建于核心 API 的,但是java.io.Externalizable的所有实现者必须提供读取和写出的实现。Java 已经具有了对序列化的内建支持,也就是说只要制作自己的类java.io.Serializable,Java 就会试图存储和重组你的对象。如果使用外部化,你就可以选择完全由自己完成读取和写出的工作,Java 对外部化所提供的唯一支持是接口:
voidreadExternal(ObjectInput in)
void writeExternal(ObjectOutput out)
现在如何实现readExternal() 和writeExternal() 就完全看你自己了。
序列化会自动存储必要的信息,用以反序列化被存储的实例,而外部化则只保存被存储的类的标识。当你通过java.io.Serializable接口序列化一个对象时,有关类的信息,比如它的属性和这些属性的类型,都与实例数据一起被存储起来。在选择走Externalizable这条路时,Java 只存储有关每个被存储类型的非常少的信息。
每个接口的优点和缺点
Serializable接口
? 优点:内建支持
? 优点:易于实现
? 缺点:占用空间过大
? 缺点:由于额外的开销导致速度变比较慢
Externalizable接口
? 优点:开销较少(程序员决定存储什么)
? 优点:可能的速度提升
? 缺点:虚拟机不提供任何帮助,也就是说所有的工作都落到了开发人员的肩上。
在两者之间如何选择要根据应用程序的需求来定。Serializable通常是最简单的解决方案,但是它可能会导致出现不可接受的性能问题或空间问题;在出现这些问题的情况下,Externalizable可能是一条可行之路。
要记住一点,如果一个类是可外部化的(Externalizable),那么Externalizable方法将被用于序列化类的实例,即使这个类型提供了Serializable方法:
private void writeObject()
private void readObject()
Externalizable 实例
被Serializable接口声明的类的对象的内容都将被序列化,如果现在用户希望自己指定序列化的内容,则可以让一个类实现Externalizable接口,此接口定义如下:
- public
interface Externalizable extendsSerializable { -
void writeExternal(ObjectOutput throwsout) IOException ; -
void readExternal(ObjectInput throwsin) IOException, - ClassNot
FoundException ; - }
Externalizable接口是Serializable接口的子接口,在此接口中定义了两个方法,这两个方法的作用如下。
writeExternal(ObjectOutput out):在此方法中指定要保存的属性信息,对象序列化时调用。
readExternal(ObjectInput in):在此方法中读取被保存的信息,对象反序列化时调用。
这两个方法的参数类型是ObjectOutput和ObjectInput,两个接口的定义如下。
ObjectOutput接口定义:
- public
interface ObjectOutput extendsDataOutput
ObjectInput接口定义:
- public
interface ObjectInput extendsDataInput
可以发现以上两个接口分别继承DataOutput和DataInput,这样在这两个方法中就可以像DataOutputStream和DataInputStream那样直接输出和读取各种类型的数据。
如果一个类要使用Externalizable实现序列化时,在此类中必须存在一个无参构造方法,因为在反序列化时会默认调用无参构造实例化对象,如果没有此无参构造,则运行时将会出现异常,这一点的实现机制与Serializable接口是不同的。
范例:修改Person类并实现Externalizable接口
- package
org.lxh.demo12.serdemo; - import
java.io.Externalizable; - import
java.io.IOException; - import
java.io.ObjectInput; - import
java.io.ObjectOutput; - public
class Person implementsExternalizable //{ 此类的对象可以被序列化 -
String //name; 声明name属性 -
int age; //声明age属性 -
Person(){} //必须定义无参构造 -
Person(String intname, age) //{ 通过构造方法设置属性内容 -
= name; -
= age; -
} -
String //toString() { 覆写toString()方法 -
"姓名:" + this.name+ ";年龄:"+ this.age; -
} -
覆写此方法,根据需要读取内容,反序列化时使用 -
void readExternal(ObjectInput throwsin) IOException, -
ClassNotFoundException { -
= //(String)in.readObject() ; 读取姓名属性 -
= //in.readInt() ; 读取年龄 -
} -
覆写此方法,根据需要可以保存属性或具体内容,序列化时使用 -
void writeExternal(ObjectOutput throwsout) IOException { -
out.writeObject( ; //保存姓名属性 -
out.writeInt( ; //保存年龄属性 -
} - }
以上程序中的Person类实现了Externalizable接口,这样用户就可以在类中有选择地保存需要的属性或者其他的具体数据。在本程序中,为了与之前的程序统一,将全部属性保存下来。
范例:序列化和反序列化Person对象
- package
org.lxh.demo12.serdemo; - import
java.io.File; - import
java.io.FileInputStream; - import
java.io.FileOutputStream; - import
java.io.InputStream; - import
java.io.ObjectInputStream; - import
java.io.ObjectOutputStream; - import
java.io.OutputStream; - public
class SerDemo03 { -
static void main(String[] throwsargs) Exception { -
ser(); 序列化 -
dser(); 反序列化 -
} -
static void ser() throwsException //{ 序列化操作 -
File f = File( "D:"+ "test.txt");File.separator + -
ObjectOutputStream oos = -
OutputStream out = FileOutputStream(f); //文件输出流 -
oos = ObjectOutputStream(out); //为对象输出流实例化 -
oos.writeObject( Person( "张三",30)); 保存对象到文件 -
oos.close(); 关闭输出 -
} -
static void dser() throwsException //{ 反序列化操作 -
File f = File( "D:"+ "test.txt");File.separator + -
ObjectInputStream ois = -
InputStream input = FileInputStream(f); //文件输出流 -
ois = ObjectInputStream(input); //为对象输出流实例化 -
Object obj = ois.readObject(); 读取对象 -
ois.close(); 关闭输出 -
System.out.println(obj); -
} - }
从以上代码中可以发现,使用Externalizable接口实现序列化明显要比使用Serializable接口实现序列化麻烦得多,除此之外,两者的实现还有不同,如表12-27所示。
表12-27
序
区
Serializable
Externalizable
1
实现复杂度
实现简单,Java对其
有内建支持
实现复杂,
由开发人员自己完成
2
执行效率
所有对象由Java统一保存,
性能较低
开发人员决定哪个对象保存,
可能造成速度提升
3
保存信息
保存时占用空间大
部分存储,
可能造成空间减少
在一般的开发中,因为Serializable接口的使用较为方便,所以出现较多
- 比较java.io.Externalizable和java.io.Serializable
- 比较java.io.Externalizable和java.io.Serializable
- 比较java.io.Externalizable和java.io.Serializable
- 比较java.io.Externalizable和java.io.Serializable
- 比较java.io.Externalizable和java.io.Serializable
- java.io.Externalizable和java.io.Serializable
- java.io.Serializable与java.io.Externalizable的比较
- java.io.Serializable与java.io.Externalizable的比较
- java序列化 java.io.Serializable和java.io.Externalizable【转】
- java.io 序列化 总结(一)---Serializable 和 Externalizable 的区别与联系
- java.io 序列化 总结(一)---Serializable 和 Externalizable 的区别与联系
- java io系列06之 序列化总结(Serializable 和 Externalizable)
- java io系列06之 序列化总结(Serializable 和 Externalizable)
- Java IO操作——对象序列化(Serializable接口、ObjectOutputStream、以及与Externalizable接口的用法和区别)
- java.io 序列化 总结Serializable 和 Externalizable 的区别与联系,以及输出后的乱码问题
- java序列化java.io.Externalizable
- java序列化java.io.Externalizable
- java序列化java.io.Externalizable
- 学习笔记:group_concat
- 防范映像劫持(IFEO HIJACK)
- 装饰模式
- Informatica PowerCenter 安装问题 .
- 一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库(三)
- 比较java.io.Externalizable和java.io.Serializable
- poj1363
- 使用IJG库读写JPEG格式文件
- 构建TI新一代高性能SOC的最小系统
- AVR单片机网址推荐 .
- 一些心得挺深刻的书
- C64X EDMA优先级及优先级队列
- ORACLE命令 CUBE
- @Override