zoukankan      html  css  js  c++  java
  • 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 + "]";
        }
     
    }
  • 相关阅读:
    UVA
    UVA
    模板——扩展欧几里得算法(求ax+by=gcd的解)
    UVA
    模板——2.2 素数筛选和合数分解
    模板——素数筛选
    Educational Codeforces Round 46 (Rated for Div. 2)
    Educational Codeforces Round 46 (Rated for Div. 2) E. We Need More Bosses
    Educational Codeforces Round 46 (Rated for Div. 2) D. Yet Another Problem On a Subsequence
    Educational Codeforces Round 46 (Rated for Div. 2) C. Covered Points Count
  • 原文地址:https://www.cnblogs.com/liruilong/p/13384093.html
Copyright © 2011-2022 走看看