专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Serializable和Externalizabl的异同

Externalizable vs Serializable

Externalizable和Serializable的一些比较点,如下:

【1】 Serializable 是标识接口

public interface Serializable {
}
public interface Externalizable extends java.io.Serializable {

    void writeExternal(ObjectOutput out) throws IOException;

    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

Externalizable 接口继承于Serializable,实现该接口,需要重写readExternal和writeExternal方法~

【2】Serializable提供了两种方式进行对象的序列化,

  • 采用默认序列化方式,将非transatient和非static的属性进行序列化
  • 编写readObject和writeObject完成部分属性的序列化

Externalizable 接口的序列化,需要重写writeExternal和readExternal方法,并且在方法中编写相关的逻辑完成序列化和反序列化。

【3】Externalizable接口的实现方式一定要有默认的无参构造函数~

  • 如果,没有无参构造函数,反序列化会报错~ 验证一下~ Book添加一个有参数的Book构造函数~
  • Serializable接口实现,其采用反射机制完成内容恢复,没有一定要有无参构造函数的限制~

【4】采用Externalizable无需产生序列化ID(serialVersionUID)~而Serializable接口则需要~

【5】相比较Serializable, Externalizable序列化、反序列更加快速,占用相比较小的内存

在项目中,大部分的类还是推荐使用Serializable, 有些类可以使用Externalizable接口,如:

  • 完全控制序列的流程和逻辑
  • 需要大量的序列化和反序列化操作,而你比较关注资源和性能~ 当然,这种情况下,我们一般还会考虑第三方序列化/反序列化工具,如protobuf等进行序列化和反序列化操作~

API的说明

Externalizabl:

25_1.png

Serializable

25_2.png

DEMO

import java.io.Serializable;
import java.util.List;

/**
 * @Type Book.java
 * @Desc 
 * @author wangmengjun
 * @date 2017年12月1日 下午7:16:29
 * @version 
 */
public class Book implements Serializable {

    private static final long serialVersionUID = -6212470156629515269L;

    /**书名*/
    private String name;

    /**ISBN*/
    private String isbn;

    /**作者*/
    private List<String> authors;

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the isbn
     */
    public String getIsbn() {
        return isbn;
    }

    /**
     * @param isbn the isbn to set
     */
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    /**
     * @return the authors
     */
    public List<String> getAuthors() {
        return authors;
    }

    /**
     * @param authors the authors to set
     */
    public void setAuthors(List<String> authors) {
        this.authors = authors;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "Book [name=" + name + ", isbn=" + isbn + ", authors=" + authors + "]";
    }

}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * @Type SerializationUtil.java
 * @Desc 
 * @author wangmengjun
 * @date 2017年12月1日 下午7:23:04
 * @version 
 */
public class SerializationUtil {

    /**
     * 从一个给定的文件完成反序列化
     */
    public static Object deserialize(String fileName) throws IOException,
            ClassNotFoundException {
        FileInputStream fis = new FileInputStream(fileName);
        BufferedInputStream bis = new BufferedInputStream(fis);
        ObjectInputStream ois = new ObjectInputStream(bis);
        Object obj = ois.readObject();
        ois.close();
        return obj;
    }

    /**
     * 将给定的对象序列化到指定的文件中去
     */
    public static void serialize(Object obj, String fileName)
            throws IOException {

        FileOutputStream fos = new FileOutputStream(fileName);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(obj);
        oos.close();
    }
}

public class SerializableTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Book book = new  Book();
        book.setIsbn("ABC123456789");
        book.setName("Hello Java");
        book.setAuthors(Arrays.asList("John","Eric"));
        //book==>Book [name=Hello Java, isbn=ABC123456789, authors=[John, Eric]]

        System.out.println("book==>" + book);

        /**
         * 将book对象序列化到book.temp文件中去
         */
        String fileName = "book.temp";
        SerializationUtil.serialize(book, fileName);

        /**
         * 从book.temp文件中,反序列化一个Book对象
         */
        Book deserializedBook = (Book) SerializationUtil.deserialize(fileName);
        //deserializedBook==>Book [name=Hello Java, isbn=ABC123456789, authors=[John, Eric]]
        System.out.println("deserializedBook==>" + deserializedBook);
    }
}

部分属性序列化

如果只想将部分属性进行序列化,可以采用如下几种方法:

1、 使用transient关键字
2、 添加writeObject和readObject方法
3、 使用Externalizable实现

使用transient关键字

public class Book implements Serializable {

    private static final long serialVersionUID = -6212470156629515269L;

    /** 书名 */
    private String name;

    /** ISBN */
    private transient String isbn;

    /** 作者 */
    private transient List<String> authors;

 ... ... 

}

重写writeObject和readObject方法

另外,我们也可以采用编写私有方法writeObject和readObject,完成部分属性的序列化。修改Book类,增加writeObject 和 readObject方法,如:

public class Book implements Serializable {

    private static final long serialVersionUID = -6212470156629515269L;

    /** 书名 */
    private String name;

    /** ISBN */
    private String isbn;

    /** 作者 */
    private List<String> authors;

    private void writeObject(ObjectOutputStream oos) throws IOException {
        // oos.defaultWriteObject();
        oos.writeObject(name);
        oos.writeObject(isbn);
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        // ois.defaultReadObject();
        name = (String) ois.readObject();
        isbn = (String) ois.readObject();
    }

... ...

}

使用Externalizable实现

还有一种方式,就是使用Externalizable完成部分属性的序列化

Externalizable继承自Serializable,使用Externalizable接口需要实现writeExternal以及readExternal方法~在writeExternal方法中,写入想要外部序列化的元素~

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;

/**
 * @Type Book.java
 * @Desc
 * @author wangmengjun
 * @date 2017年12月1日 下午7:16:29
 * @version
 */
public class Book implements Externalizable {

    /** 书名 */
    private String name;

    /** ISBN */
    private String isbn;

    /** 作者 */
    private List<String> authors;

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeObject(isbn);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        isbn = (String) in.readObject();
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the isbn
     */
    public String getIsbn() {
        return isbn;
    }

    /**
     * @param isbn
     *            the isbn to set
     */
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    /**
     * @return the authors
     */
    public List<String> getAuthors() {
        return authors;
    }

    /**
     * @param authors
     *            the authors to set
     */
    public void setAuthors(List<String> authors) {
        this.authors = authors;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "Book [name=" + name + ", isbn=" + isbn + ", authors=" + authors + "]";
    }

}

文章永久链接:https://tech.souyunku.com/30566

未经允许不得转载:搜云库技术团队 » Serializable和Externalizabl的异同

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们