• 为什么实现Serializbale接口就能够进行序列化?


    从所周知,Serializbale接口是个空的接口,并没有定义任何方法。那么问题来了,为什么需要序列化的接口只要实现Serializbale接口就能够进行序列化?

    这要从序列化过程的源码说起。举个例子这里有个可序列化的Parent类,然后我们用一个TestSeri类对其序列化。

    public class Parent implements Serializable {
    
        private static final long serialVersionUID = 1234L;
        
        public Parent1(String name,int age){
            this.name = name;
            this.age = age;
        }
        
        private String name;
        private int age;
    
        
        public String toString(){
            return "Parent:"+name+" "+age;
        }
        
    }
    public class TestSeri {
        
        public static  void seri(Parent parent){
            try {
                FileOutputStream fo = new FileOutputStream("src/est.txt");
                ObjectOutputStream oos = new ObjectOutputStream(fo);
                oos.writeObject(parent);
                oos.flush();
                oos.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }        
        }
        
        public static void main(String[] args){
            Parent parent = new Parent("ouym",24);
            seri(parent);
                    
        }

    序列话的过程主要有三步:

    (1)新建文件输出流用来指定一个位置存储序列化的内容。

    (2)新建一个ObjectOutputStream对象oos

    (3)序列化:调用writeObject(parent)方法。

    关键看第三部writeObject的内部实现过程:

    public final void writeObject(Object obj) throws IOException {
        //省略部分代码
        try {
            // 调用writeObject0()方法序列化
            writeObject0(obj, false);
        } catch (IOException ex) {
            if (depth == 0) {
                writeFatalException(ex);
            }
            throw ex;
        }
    }

    可见writeObject方法的主要实现过程交给了writeObject0(obj,false)方法。

     1 private void writeObject0(Object obj, boolean unshared)
     2     throws IOException
     3 {
     4     // 一些省略代码
     5     try {
     6         // 一些省略代码,其他的细节我们不深入
     7         // remaining cases
     8         if (obj instanceof String) {
     9             writeString((String) obj, unshared);
    10         } else if (cl.isArray()) {
    11             writeArray(obj, desc, unshared);
    12         } else if (obj instanceof Enum) {
    13             writeEnum((Enum) obj, desc, unshared);
    14         } else if (obj instanceof Serializable) {
    15             // 被序列化对象实现了Serializable接口
    16             writeOrdinaryObject(obj, desc, unshared);
    17         } else {
    18             if (extendedDebugInfo) {
    19                 throw new NotSerializableException(
    20                     cl.getName() + "
    " + debugInfoStack.toString());
    21             } else {
    22                 throw new NotSerializableException(cl.getName());
    23             }
    24         }
    25     } finally {
    26         depth--;
    27         bout.setBlockDataMode(oldMode);
    28     }
    29 }

    从上述代码第8行开始,我们知道String,数组和枚举类型可以直接序列化(不难猜出String和Enum类实现了Serializbale接口)。若不是上述三种类型的话,接下来重点看14到16行代码,如果对象实现了Serializbale接口的话,就用writeOrdinaryObject()方法进行序列化操作。这里我们就不看writeOrdinaryObject方法的细节了,因为我们已经找到了标题的答案。Serializable接口这是一个标识,告诉程序所有实现了他的对象都可以进行序列化。

    更多关于序列化的详情推荐大神博客:http://www.importnew.com/24490.html

  • 相关阅读:
    JSON 字符串 与 java 对象的转换
    DNS解析过程详解
    全面了解移动端DNS域名劫持等杂症:原理、根源、HttpDNS解决方案等
    TCP Send函数的阻塞和非阻塞,以及TCP发送数据的异常情况
    基于TCP协议的应用层的ACK机制
    Golang的反射reflect深入理解和示例
    C/C++中struct中内存对齐规则
    Go 包依赖管理工具 —— govendor
    什么是幂等?什么情况下需要考虑幂等?怎么解决幂等的问题?
    Golang 中间件简介 MiddleWare
  • 原文地址:https://www.cnblogs.com/ouym/p/8795885.html
Copyright © 2020-2023  润新知