java 序列化和反序列化的實現原理


老是聽說序列化反序列化,就是不知道到底什么是序列化,什么是反序列化?今天就在網上搜索學習一下,這一搜不要緊,發現自己曾經用過,竟然不知道那就是JDK類庫中序列化和反序列化的API。

 

----什么是序列化?

--1--java序列化是指把java對象轉換為字節序列的過程,而java反序列化是指把字節序列恢復為java對象的過程

--2--序列化:對象序列化的最主要的用處就是在傳遞和保存對象的時候,保證對象的完整性和可傳遞性。序列化是把對象轉換成有序字節流,以便在網絡上傳輸或者保存在本地文件中。序列化后的字節流保存的java對象的狀態以及相關的描述信息。序列化機制的核心作用就是對象狀態的保存與重建。

--3--反序列化:客戶端從文件中或網絡上獲得序列化后的對象字節流后,根據字節流中所保存的對象狀態及描述信息,通過反序列化重建對象。

--4--序列化就是把實體對象狀態按照一定的格式寫入到有序字節流,反序列化就是從有序字節流重建對象,恢復對象狀態

 

----為什么需要序列化與反序列化

當兩個進程進行遠程通信時,可以相互發送各種類型的數據,包括文本,圖片,音頻,視頻等,而這些數據都會以二進制的形式在網絡上傳送。

當兩個java進行進行通信時,要傳送對象,怎么傳對象,通過序列化與反序列化。

也就是說,發送方需要把對象轉換為字節序列,然后在網絡上傳送,另一方面,接收方需要從字節序列中恢復出java對象

 

----序列化的好處

--1--永久性保存對象,保存對象的字節序列到本地文件或者數據庫中,實現了數據的持久化,通過序列化可以把數據永久的保存到硬盤上,

--2--利用序列化實現遠程通信,可以在網絡上傳送對象的字節序列。

--3--在進程間傳遞對象

 

 

----序列化算法步驟

--1--把對象實例相關的類元數據輸出

--2--遞歸輸出類的超類描述直到不再有超類

--3--類元數據完了以后,開始從最懂曾的超類開始輸出對象實例的實際數據值。

--4--從上至下遞歸輸出實例的數據

 

 

 ----Java 如何實現序列化和反序列化

--1-- JDK類庫中序列化API

java.io.ObjectOutputStream: 表示輸出對象流

它的writeObject(Object obj)方法可以對參數指定的obj對象進行序列化,把得到的字節序列寫到一個目標輸出流中;

--2--java.io.ObjectInputStream:表示對象輸入流

它的readObject()方法源輸入流中讀取字節序列,再把它們反序列化成為一個對象,並將其返回

 

--2--實現序列化的要求

只有實現了Serializable或Externalizable接口的對象才能被序列化,否則拋出異常!

 

--3--實現java對象序列化與反序列化的方法

 

例 a 類,它的對象需要序列化,有3種方法

如果類a僅僅實現了Serializable接口,則

ObjectOutputStream采用默認的序列化方式,對a對象的非transient實例變量進行序列化

ObjectInputStream采用默認的反序列化方式,對a對象的非transient實例變量進行反序列化

如果類a僅僅實現了Serializable接口,並且還定義了a對象的writeObject(ObjectOutputStream out) 和readObject(ObjectInputStream in),則

ObjectOutputStream調用a對象的writeObject(ObjectOutputStream out)的方法進行序列化

ObjectInputStream調用a對象的readObject(ObjectInputStream in)的方法進行序列化

如果a類實現了ExternaInalizable接口,且User類必須實現readExternam(ObjectInput in)和wiriteExternal(ObjectOutput out)方法,則

ObjectOutputStream調用a對象的wiriteExternal(ObjectOutput out)的方法進行序列化

ObjectInputStream調用a對象的readExternam(ObjectInput in)的方法進行序列化‘’

 

 ----JDK類庫中序列化的步驟

--1--創建一個對象輸出流,它可以包裝一個奇特類型的目標輸出流,如文件輸出流:

objectOutputStream oos=new objectOutputStream(new FileOutStream(c:\\object.out));

--2--通過對象輸出流writeObject()方法寫對象:

oos.writeObject(new a("xiaoxiao","145263","female"));

 

----JDK類庫中反序列化的步驟

--1--創建一個對象輸入流,它可以包裝一個其他類型輸入流,如文件輸入流:

objectInputStream ois=new ObjectInputStream(new FileInputStream("object.out"));

--2--通過對象輸出流的readObject()方法讀取對象:

a aa=(a)ois.readObject();

--3--為了正確讀數據,完成反序列化,必須保證向對象輸出流寫對象的順序與從對象輸入流中讀對象的順序一致

 

 ----例子

import java.awt.print.Printable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


public class SerialDemo {
       public static void main(String[] args) throws IOException,ClassNotFoundException{
              
              FileOutputStream fos =new FileOutputStream("object.out");
              ObjectOutputStream oos=new ObjectOutputStream(fos);
              User user1=new User("xiaoming","145263","female");
              oos.writeObject(user1);
              System.out.print(oos);
              oos.flush();
              oos.close();
              
              FileInputStream fis=new FileInputStream("object.out");
              ObjectInputStream ois=new ObjectInputStream(fis);
              User user2=(User) ois.readObject();
              System.out.print(user2.getUserName("xiaoming")+" "+ user2.getPassword("145263")+" " + user2.getSex("female"));
       }
}



import java.io.Serializable;

public class User implements Serializable {
       public User(String string, String string2, String string3) {
              // TODO Auto-generated constructor stub
       }
       private String userName;
       private String password;
       private String sex;
       
       public String getUserName(String userName) {
              return userName;
       }
       public String getPassword(String password) {
              return password;
       }
       public String getSex(String sex) {
              return sex;
       }
}

 

 文件位置

 

 

 

 

學習自 : https://blog.csdn.net/xlgen157387/article/details/79840134


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM