zoukankan      html  css  js  c++  java
  • Serializable接口的背后

    序列化是什么?

      序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。序列化分为两大部分:序列化和反序列化。

    • 序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。
    • 反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例

    什么时候使用序列化: 

    • 对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
    • java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。

    序列化的特点:

    • 如果某个类能够被序列化,其子类也可以被序列化。如果该类有父类,则分两种情况来考虑,如果该父类已经实现了可序列化接口。则其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现可序列化接口,则该类的父类所有的字段属性将不会序列化。 (2)声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态, transient代表对象的临时数据;
    • 相关的类和接口:在java.io包中提供的涉及对象的序列化的类与接口有ObjectOutput接口、ObjectOutputStream类、ObjectInput接口、ObjectInputStream类。
      • ObjectOutput接口:它继承DataOutput接口并且支持对象的序列化,其内的writeObject()方法实现存储一个对象。ObjectInput接口:它继承DataInput接口并且支持对象的序列化,其内的readObject()方法实现读取一个对象。
      • ObjectOutputStream类:它继承OutputStream类并且实现ObjectOutput接口。利用该类来实现将对象存储(调用ObjectOutput接口中的writeObject()方法)。ObjectInputStream类:它继承InputStream类并且实现ObjectInput接口。利用该类来实现读取一个对象(调用ObjectInput接口中的readObject()方法)。


      对于父类的处理,如果父类没有实现序列化接口,则其必须有默认的构造函数(即没有参数的构造函数)。否则编译的时候就会报错。在反序列化的时候,默认构造函数会被调用。但是若把父类标记为可以序列化,则在反序列化的时候,其默认构造函数不会被调用。这是为什么呢?这是因为Java 对序列化的对象进行反序列化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成。

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    /**
     * Author: Leo Sun
     * Blog: http://kaffa.im/
     * Date: Aug 12, 2014
     */
    public class SerializableDemo {
    
        public static void main(String[] args) {
            Cat cat = new Cat();
            try {
                FileOutputStream fos = new FileOutputStream("catDemo.out");
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                System.out.println(" 1> " + cat.getName());
                cat.setName("My Cat");
                oos.writeObject(cat);
                oos.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            try {
                FileInputStream fis = new FileInputStream("catDemo.out");
                ObjectInputStream ois = new ObjectInputStream(fis);
                cat = (Cat) ois.readObject();
                System.out.println(" 2> " + cat.getName());
                ois.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    
    class Cat implements Serializable {
        
        private static final long serialVersionUID = -5426949996723910122L;
        private String name;
    
        public Cat() {
            this.name = "new cat";
        }
    
        public String getName() {
            return this.name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    注:writeObject和readObject本身就是线程安全的,传输过程中是不允许被并发访问的。所以对象能一个一个接连不断的传过来

  • 相关阅读:
    [LeetCode] Convert Sorted Array to Binary Search Tree
    [LeetCode] Diameter of Binary Tree
    [LeetCode] Student Attendance Record I
    [LeetCode] Reverse String II
    [LeetCode] Missing Number
    [LeetCode] Intersection of Two Arrays II
    [LeetCode] Base 7
    Ubuntu中firefox设置成中文
    Linux中的查找命令find
    Ubuntu14.04安装配置Chrome浏览器
  • 原文地址:https://www.cnblogs.com/fuxinci/p/3908581.html
Copyright © 2011-2022 走看看