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:

Serializable

 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://www.cnblogs.com/liruilong/p/13384093.html