被Serializable接口声明的类的对象的内容都将被序列化,如果现在用户希望自己指定序列化的内容,则可以让一个类实现Externalizable接口,此接口定义如下:

 public interface Externalizable extends Serializable {
public void writeExternal(ObjectOutput out) throws IOException;
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

Externalizable接口是Serializable接口的子接口,在此接口中定义了两个方法,这两个方法的作用如下。

writeExternal(ObjectOutputout):在此方法中指定要保存的属性信息,对象序列化时调用。

readExternal(ObjectInputin):在此方法中读取被保存的信息,对象反序列化时调用。

这两个方法的参数类型是ObjectOutput和ObjectInput,两个接口的定义如下。

ObjectOutput接口定义:

  1. public interface ObjectOutput extends DataOutput

ObjectInput接口定义:

  1. public interface ObjectInput extends DataInput

可以发现以上两个接口分别继承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 implements Externalizable { private String name; // 声明name属性 private int age; // 声明age属性 public Person(){} // 必须定义无参构造 public Person(String name, int age) { // 通过构造方法设置属性内容
this.name = name;
this.age = age;
} public String toString() { // 覆写toString()方法
return "姓名:" + this.name + ";年龄:" + this.age;
} // 覆写此方法,根据需要读取内容,反序列化时使用
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
this.name = (String)in.readObject() ; // 读取姓名属性
this.age = in.readInt() ; // 读取年龄
}
// 覆写此方法,根据需要可以保存属性或具体内容,序列化时使用
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(this.name) ; // 保存姓名属性
out.writeInt(this.age) ; // 保存年龄属性
}
}

以上程序中的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 {
public static void main(String[] args) throws Exception {
ser(); // 序列化
dser(); // 反序列化
}
public static void ser() throws Exception { // 序列化操作
File f = new File("D:" + File.separator + "test.txt");
ObjectOutputStream oos = null;
OutputStream out = new FileOutputStream(f); // 文件输出流
oos = new ObjectOutputStream(out); // 为对象输出流实例化
oos.writeObject(new Person("张三", 30)); // 保存对象到文件
oos.close(); // 关闭输出
}
public static void dser() throws Exception { // 反序列化操作
File f = new File("D:" + File.separator + "test.txt");
ObjectInputStream ois = null;
InputStream input = new FileInputStream(f); // 文件输出流
ois = new ObjectInputStream(input); // 为对象输出流实例化
Object obj = ois.readObject(); // 读取对象
ois.close(); // 关闭输出
System.out.println(obj);
}
}

从以上代码中可以发现,使用Externalizable接口实现序列化明显要比使用Serializable接口实现序列化麻烦得多,除此之外,两者的实现还有不同,如表12-27所示。

表12-27 Externalizable接口与Serializable接口实现序列化的区别

序   号

区   别

Serializable

Externalizable

1

实现复杂度

实现简单,Java对其

有内建支持

实现复杂,

由开发人员自己完成

2

执行效率

所有对象由Java统一保存,

性能较低

开发人员决定哪个对象保存,

可能造成速度提升

3

保存信息

保存时占用空间大

部分存储,

可能造成空间减少

在一般的开发中,因为Serializable接口的使用较为方便,所以出现较多

[转]Serializable接口与Externalizable接口区别的更多相关文章

  1. Java中实现序列化的两种方式 Serializable 接口和 Externalizable接口

    对象的序列化就是将对象写入输出流中. 反序列化就是从输入流中将对象读取出来. 用来实现序列化的类都在java.io包中,我们常用的类或接口有: ObjectOutputStream:提供序列化对象并把 ...

  2. Java基础(十一)--Serializable和Externalizable接口实现序列化

    序列化在日常开发中经常用到,特别是涉及到网络传输的时候,例如调用第三方接口,通过一个约定好的实体进行传输,这时你必须实现序列 化,这些都是大家都了解的内容,所以文章也会讲一下序列化的高级内容. 序列化 ...

  3. Externalizable接口 序列化

    Java默认的序列化机制非常简单,而且序列化后的对象不需要再次调用构造器重新生成,但是在实际中,我们可以会希望对象的某一部分不需要被序列化,或者说一个对象被还原之后, 其内部的某些子对象需要重新创建, ...

  4. Java基础知识强化104:Serializable接口 与 Parcelable接口

    1. 什么是 序列化 和 反序列化 ?     序列化 :序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序 ...

  5. 如何使用Externalizable接口自定义Java中的序列化

    Java序列化过程的缺点 我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject 和readObject方法自定义序列化过程. 但是这些自定义还不够 ...

  6. Java 8 中的抽象类和接口到底有啥区别?

    上一篇栈长发了这篇<Java 8 有多牛逼?打破一切你对接口的认知!>,帮助许多人解开了疑惑,还有读者留言说两者还有啥区别,故引发了此篇: 在我们面试时也会经常遇到面试官问抽象类和接口的区 ...

  7. android中接口和抽象类的区别

    最近发现很多基础有点生疏了,特地写一点博客来巩固一下.今天主要来谈谈接口和抽象类的区别,我们在项目的很多地方都会用到接口或者抽象类,但是它们之间的一些区别和相同点不知道大家有没有注意到,还有就是,什么 ...

  8. Java接口和抽象类的区别

    今天看到项目中,写了一个抽象类,里面有很多方法继承了这类,当调用这个接口时,采用的是这个抽象类去调方法的,当时一想,这个不就是我们说的Java的多态的特征: 继承:存在继承关系的子类和父类 重写:子类 ...

  9. java 接口和抽象类的区别

    java 接口和抽象类的区别抽象类:1.含有抽象方法的类一定为抽象类,反过来抽象类,不一定含有抽象方法:2.抽象类必须用abstract来进行定义,抽象方法也必须用abstract来进行定义:3.抽象 ...

随机推荐

  1. Aimbat安装

    1:Pysmo下的sac和aimbat需要放在和前面的toolkits 相同的地方,Python就能找到: 在安装obspy时,需要装yum-plugin-copr; 方法在网址: https://c ...

  2. tensorflow-可视化

    先学习几个英文单词 summary 汇总,摘要 scope 范围 我这是很早以前的笔记,后来有了博客才发布的,有些内容比较老,懒得改了.  先说明总体流程 暂时不管怎么编程,假设已经有了如下代码,可执 ...

  3. Linux文件系统命令 cp

    命令名:cp 功能:拷贝文件,把一个文件的内容拷贝到另外一个文件中去. eg: cp source_file dist_file renjg@renjg-HP-Compaq-Pro--MT:~$ cp ...

  4. 初识Linux------虚拟机VM三种配置网络的解说

    桥接模式: 相当于在物理主机与虚拟机网卡之间架设了一座桥梁,从而可以通过物理主机的网卡访问外网. NAT模式: 让 VM 虚拟机的网络服务发挥路由器的作用,使得通过虚拟机软件模拟的主机可以通过物理主 ...

  5. python基础题型一

    一.执行Python脚本的两种方式 #python name.py   Python解析器 #chmod +x name.py 二.简述位.字节的关系 1Byte=8bit 三.简述ascii.uni ...

  6. Vuejs 用$emit 与 $on 来进行兄弟组件之间的数据传输

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. django做redis缓存

    django中应用redis:pip3 install django-redis - 配置 CACHES = { "default": { "BACKEND": ...

  8. C++ SUBLIME TEXT3 环境配置

    一.第一种方法 1.New Build System,设置C++.sublime-build编译文件 { "path": "E:\\MinGW\\bin", & ...

  9. FreeSWITCH视频会议命令

    列出所有会议 conference list 列出会议的所有成员 conference <conference_name> list 而<conference_name>就是会 ...

  10. Non-technical Blog Recording on Day of Sep. 19th 2017 in Retrospection.

    Unfortunately, I heard a resignation message verbally from ESU (her name is: Su Yi in Chinese, Su fr ...