Serializable接口与Externalizable接口区别

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

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

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

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

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

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

ObjectOutput接口定义:

public interface ObjectOutput extends DataOutput 

ObjectInput接口定义:

public interface ObjectInput extends DataInput 

可以发现以上两个接口分别继承DataOutput和DataInput,这样在这两个方法中就可以像DataOutputStream和DataInputStream那样直接输出和读取各种类型的数据。

如果一个类要使用Externalizable实现序列化时,在此类中必须存在一个无参构造方法,因为在反序列化时会默认调用无参构造实例化对象,如果没有此无参构造,则运行时将会出现异常,这一点的实现机制与Serializable接口是不同的。

范例:修改Person类并实现Externalizable接口

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接口实现序列化麻烦得多,除此之外,两者的实现还有不同,如下表所示。

序   号

区   别

Serializable

Externalizable

1

实现复杂度

实现简单,Java对其

有内建支持

实现复杂,

由开发人员自己完成

2

执行效率

所有对象由Java统一保存,

性能较低

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

可能造成速度提升

3

保存信息

保存时占用空间大

部分存储,

可能造成空间减少

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

原文地址

全部评论

相关推荐

这就是上等人的社会吗:都先停一停,有没有hxd告诉我在哪里点京东外卖,捣鼓半天,注册成了专送骑手查看图片
投递美团等公司6个岗位 > 京东美团大战,你怎么看?
点赞 评论 收藏
分享
群星之怒:1.照片可以换更好一点的,可以适量P图,带一些发型,遮住额头,最好穿的正式一点,可以适当P图。2.内容太少。建议添加的:求职意向(随着投递岗位动态更改);项目经历(内容太少了建议添加一些说明,技术栈:用到了什么技术,还有你是怎么实现的,比如如何确保数据传输稳定的,角色注册用到了什么技术等等。)项目经历是大头,没有实习是硬伤,如果项目经理不突出的话基本很难过简历筛。3.有些内容不必要,比如自我评价,校内实践。如果实践和工作无关千万别写,不如多丰富丰富项目。4.排版建议:建议排版是先基础信息,然后教育背景(要突出和工作相关的课程),然后专业技能(一定要简短,不要长篇大论,写你会什么,会的程度就可以),然后是项目经历(一定要详细,占整个简历一定要超过一半,甚至超过百分之70都可以)。最后如果有一部分空白的话可以填补上校内获得的专业相关的奖项,没有就写点校园经历和自我评价。5.技术一定要够硬,禁得住拷打。还有作息尽量保证正常,不要太焦虑。我24双非本科还是非科班,秋招春招各找了一段实习结果都没有转正,当时都想噶了,最后6月份在校的尾巴也找到一份工作干到现在,找工作有时很看运气的不要急着自我否定。 加油
点赞 评论 收藏
分享
03-18 09:45
莆田学院 golang
牛客749342647号:佬,你这个简历模板是哪个,好好看
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务