首頁  >  問答  >  主體

序列化 - 如何理解java.io.Serializable接口

java.io.Serializable是一个没有任何待实现方法的接口,此接口在对象序列化的过程中起到了什么作用?或者此接口在java序列化机制中扮演什么角色?

伊谢尔伦伊谢尔伦2767 天前475

全部回覆(2)我來回復

  • 巴扎黑

    巴扎黑2017-04-17 12:05:04

    Java平台允許我們在記憶體中建立可重複使用的Java對象,但一般情況下,只有當JVM處於運行時,這些對象才可能存在,即,這些對象的生命週期不會比JVM的生命週期更長。但在現實應用中,就可能要求在JVM停止運行之後能夠保存(持久化)指定的對象,並在將來重新讀取被保存的對象。 Java物件序列化就能夠幫助我們實現該功能。
    摘錄自http://www.blogjava.net/jiangshachina/archive/2012/02/13/369898.html
    PS:連結文章有詳細的使用範例喲

    大白話就是這個介面允許你把記憶體裡你實例化的對象,當做檔案保存下來。有什麼用呢,舉幾個栗子
    1.遊戲存檔:把主角這個實力物件保存成文件,下次打開遊戲就可以加載,接著玩啦哇
    2.網路通訊:一個機器上實例的對象,要傳給另一台機器,先保存成文件再傳哇


    題主改題之後

    你是想了解序列化的機制對吧,既然你誠心誠意的發問了,武藏小次郎~~~~~

    好吧來看一下使用ObjectOutputStream類別持久化一個物件的過程,writeObject0(Object obj, boolean unshared) 函數的來源碼1170~1185行(JDK 1.7.0_45)

     if (obj instanceof String) {
        writeString((String) obj, unshared);
    } else if (cl.isArray()) {
        writeArray(obj, desc, unshared);
    } else if (obj instanceof Enum) {
        writeEnum((Enum) obj, desc, unshared);
    } else if (obj instanceof Serializable) {
        writeOrdinaryObject(obj, desc, unshared);
    } else {
        if (extendedDebugInfo) {
            throw new NotSerializableException(
                cl.getName() + "\n" + debugInfoStack.toString());
        } else {
            throw new NotSerializableException(cl.getName());
        }
    }
    

    看到了吧,物件如果是String、是陣列、是枚舉、是Serializable就對應的函數把物件寫成檔案否則拋出錯誤,扮演什麼角色呢,就是一個標誌而已。

    如果僅僅只是讓某個類別實現Serializable接口,而沒有其它任何處理的話,則就是使用預設序列化機制。使用預設機制,在序列化物件時,不僅會序列化當前物件本身,還會對該物件引用的其它物件也進行序列化,同樣地,這些其它物件引用的另外物件也將被序列化,以此類推。所以,如果一個物件包含的成員變數是容器類別對象,而這些容器所含有的元素也是容器類別對象,那麼這個序列化的過程就會較複雜,而且開銷也較大。
    依然摘抄與上個連結

    Externalizable繼承自Serializable,當使用此介面時,序列化的細節需要由程式設計師去完成。我想你需要這個~~~

    回覆
    0
  • 黄舟

    黄舟2017-04-17 12:05:04

    空介面在使用 instanceof 來判斷類型的時候就有用了

    public class Test {
        public static void main(String[] args) {
            T1 t1 = new T1();
            T2 t2 = new T2();
    
            System.out.println("t1: " + (t1 instanceof java.io.Serializable));
            System.out.println("t1: " + (t2 instanceof java.io.Serializable));
        }
    }
    
    class T1 {}
    
    class T2 implements java.io.Serializable {}
    
    

    如果你看 OpenJDK 的源碼,你可以看到 ObjectOutputStream.java 中有這麼一段與之有關的程式碼:

                // remaining cases
                if (obj instanceof String) {
                    writeString((String) obj, unshared);
                } else if (cl.isArray()) {
                    writeArray(obj, desc, unshared);
                } else if (obj instanceof Enum) {
                    writeEnum((Enum) obj, desc, unshared);
                } else if (obj instanceof Serializable) {
                    writeOrdinaryObject(obj, desc, unshared);
                } else {
                    if (extendedDebugInfo) {
                        throw new NotSerializableException(
                            cl.getName() + "\n" + debugInfoStack.toString());
                    } else {
                        throw new NotSerializableException(cl.getName());
                    }
                }
    

    原始碼參考 http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/d1f592073a0e/src/share/classes/java/io/ObjectOutputStream.java 第 1176

    回覆
    0
  • 取消回覆