首頁  >  文章  >  Java  >  Java序列化與反序列化怎麼應用

Java序列化與反序列化怎麼應用

PHPz
PHPz轉載
2023-04-29 17:37:141302瀏覽

    Java 序列化與反序列化

    Java序列化把一個物件Java Object變成一個二進位位元組序列byte[]

    Java反序列化就是把一個二進位位元組序列byte[] 變成Java物件Java Object

    #序列化API

    ObjectOutputStream

    位元組輸出流對象,將對象的輸出流寫到文件中(結合FileOutputStream使用)

    實例:

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
    或
    FileOutputStream fout = new FileOutputStream("1.txt");
    ObjectOutputStream out = new ObjectOutputStream(fout);

    此外ObjectOutputStream也提供了

    writeObject()

    方法來序列化一個對象,並將它傳送到輸出流。

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
    out.writeObject(new Test("Sentiment",10));        //对Test类中的构造方法进行传参

    ObjectInputStream

    Java序列化與反序列化怎麼應用位元組輸入流對象,將檔案中的二進位位元組序列進行反序列化操作(結合FileInputStream)

    實例:

    ObjectInputStream in = new ObjectInputStream(new FileInputStream("1.txt"));
    或
    FileInputStream fin = new FileInputStream("1.txt");
    ObjectInputStream oin = new ObjectInputStream(fin);

    此外ObjectInputStream也提供Java序列化與反序列化怎麼應用readObject()

    方法從流中取出下一個對象,並將物件反序列化。它的傳回值為Object,因此,需要將它轉換成合適的資料類型。

    ObjectInputStream In = new ObjectInputStream(new FileInputStream("1.txt"));
    Test o = (Test)In.readObject();
    System.out.println(o);        //读取后输出实例理解

    實例理解
    • Test.java(類別想要進行序列化操作,必須實作Serializable介面繼承)

      package Sentiment.unserialize.demo01;
      
      import java.io.Serializable;
      
      public class Test implements Serializable {
          private String name;
          private int age;
      
          public Test() {
          }
      
          public Test(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Test{" + "name='" + name + '\'' + ", age=" + age + '}';
          }
      
      }

      Serializable.java
    • package Sentiment.unserialize.demo01;
      
      import java.io.*;
      
      public class Serializable {
          public static void main(String[] args) throws IOException {
              ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
              out.writeObject(new Test("Sentiment",10));
              out.close();
          }
      }
    • UnSerializable.java

      package Sentiment.unserialize.demo01;
      
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.io.ObjectInputStream;
      
      public class UnSerializable {
          public static void main(String[] args) throws IOException, ClassNotFoundException {
              ObjectInputStream In = new ObjectInputStream(new FileInputStream("1.txt"));
              Test o = (Test)In.readObject();
              System.out.println(o);
          }
      }

      執行Serializable.java後得到二進位字節碼檔內容
    • 此時在執行UnSerializable.java便得到了二進位字節碼反序列化後的內容

    serialVersionUID

    每個可序列化的類別在序列化時都會關聯一個版本號, 這個版本號碼就是serialVersionUID 屬性

    serialVersionUID 屬性必須透過static final long 修飾符來修飾。

    Java序列化與反序列化怎麼應用

    如果可序列化的類別未宣告serialVersionUID 屬性, 則Java 序列化時會根據類別的各種資訊來計算預設的serialVersionUID 值. 但是Oracle 官方文件強烈建議所有可序列化的類別都顯示宣告serialVersionUID 值.

    實例理解

    在Test.java定義serialVersionUID 其值為1 <pre class="brush:java;">package Sentiment.unserialize.demo01; import java.io.Serializable; public class Test implements Serializable { public static final long serialVersionUID = 1L; //定义serialVersionUID private String name; private int age; public Test() { } public Test(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return &quot;Test{&quot; + &quot;name=&amp;#39;&quot; + name + &amp;#39;\&amp;#39;&amp;#39; + &quot;, age=&quot; + age + &amp;#39;}&amp;#39;; } }</pre>此時執行Serializable.java進行序列化操作 完成完成後將serialVersionUID的值定義為2—>public static final long serialVersionUID = 2L;,在運作UnSerializable.java會報錯誤

    Java序列化與反序列化怎麼應用Transient (瞬態變數)

    Transient( 瞬態變數)是個Java 關鍵字, 它用於標記類別的成員變數在持久化到位元組流時不要被序列化; 在透過網路套接字流傳輸位元組流時, transient 關鍵字標記的成員變數不會被序列化。此為被static修飾的靜態變數也不參與序列化操作。

    實例理解

    將Test.java中的

    name

    age

    變數前分別加上Java序列化與反序列化怎麼應用transient

    和## #static######
    package Sentiment.unserialize.demo01;
    
    import java.io.Serializable;
    
    public class Test implements Serializable {
        public static final long serialVersionUID = 1L;  //定义serialVersionUID 
        private transient String name;                     //加上transient
        private static int age;                             //加上static
    
        public Test() {
        }
    
        public Test(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Test{" + "name=&#39;" + name + &#39;\&#39;&#39; + ", age=" + age + &#39;}&#39;;
        }
    
    }
    ###此時在執行Serializable.java和UnSerializable.java,輸出結果:Sentiment—>null,10—>0############ ###readObject()方法重寫######官方允許使用者在被序列化的類別中重寫readObject() 方法, 重寫後的方法將負責在反序列化時重構目前類別物件.使用者只需要在重寫的readObject() 方法中實作defaultReadObject() 方法, 就可以確保反序列化過程正常執行.######實例理解######實作defaultReadObject() 方法呼叫,並在Test類別中重寫該方法,在進行序列化和反序列化操作即可執行命令###
    private void readObject(java.io.ObjectInputStream a) throws IOException, ClassNotFoundException{
        a.defaultReadObject();
        Runtime.getRuntime().exec("calc.exe");
    }
    #########

    以上是Java序列化與反序列化怎麼應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除