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 + "]";
        }
     
    }
  • 相关阅读:
    HDU_1016——素环问题DFS
    什么是REST?以及RESTful的实现
    WebApi系列~基于RESTful标准的Web Api
    理解RESTful架构
    国内技术管理人员批阅google的“春运交通图”项目
    项目质量量化考核建议
    设计模式在交易系统中的应用
    修改Chrome临时文件位置
    百度员工离职总结:如何做个好员工?
    Firebird数据库系统的开发团队
  • 原文地址:https://www.cnblogs.com/liruilong/p/13384093.html
Copyright © 2011-2022 走看看