在高階Java中,序列化和反序列化是保存和復原物件狀態的過程,使得可以將物件儲存在檔案或資料庫中,或透過網路傳輸它們。以下是這些概念及其應用的詳細介紹
1️⃣連載
序列化是將物件轉換為位元組流的過程。此位元組流可以儲存到檔案中、透過網路傳送或儲存在資料庫中。在Java中,Serialized介面用來表示類別可以被序列化。
✍ 序列化物件的步驟:
▶️ 實作 Serialized 介面。
▶️ 使用 ObjectOutputStream 和 FileOutputStream 將物件寫入檔案或輸出流。
▶️ 在 ObjectOutputStream 上呼叫 writeObject() 方法。
?程式碼範例:
import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class Employee implements Serializable { private static final long serialVersionUID = 1L; String name; int id; public Employee(String name, int id) { this.name = name; this.id = id; } } public class SerializeDemo { public static void main(String[] args) { Employee emp = new Employee("John Doe", 101); try (FileOutputStream fileOut = new FileOutputStream("employee.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut)) { out.writeObject(emp); System.out.println("Serialized data is saved in employee.ser"); } catch (Exception e) { e.printStackTrace(); } } }
這裡,employee.ser 是一個儲存物件位元組流的序列化檔案。
2️⃣ 反序列化
反序列化是相反的過程,其中位元組流被轉換回原始物件的副本。這使您能夠在儲存或傳輸物件後重新建立物件的狀態。
✍ 反序列化物件的步驟:
▶️ 使用 ObjectInputStream 和 FileInputStream 從檔案或輸入流中讀取物件。
▶️ 呼叫 ObjectInputStrea 上的 readObject() 方法
?程式碼範例:
import java.io.FileInputStream; import java.io.ObjectInputStream; public class DeserializeDemo { public static void main(String[] args) { Employee emp = null; try (FileInputStream fileIn = new FileInputStream("employee.ser"); ObjectInputStream in = new ObjectInputStream(fileIn)) { emp = (Employee) in.readObject(); System.out.println("Deserialized Employee..."); System.out.println("Name: " + emp.name); System.out.println("ID: " + emp.id); } catch (Exception e) { e.printStackTrace(); } } }
這將檢索物件的原始狀態,允許存取其字段,就像序列化之前一樣。
3️⃣ 進階連載主題
▶️ 自訂序列化:重寫 writeObject() 和 readObject() 以進行自訂序列化。
▶️ 可外部化介面:提供序列化的完全控制,需要實作 writeExternal() 和 readExternal() 方法。
▶️ 瞬態欄位:使用瞬態關鍵字來避免序列化特定欄位(例如密碼等敏感資料)。
✍ 序列化的優點:
▶️ 允許保存物件的狀態以供將來使用。
▶️ 促進複雜資料物件通過網路的傳輸。
?簡單解釋一下程式碼範例
import java.io.*; class Student implements Serializable { private static final long serialVersionUId = 1l; private String name ; private int age; private String Address; public Student(String name,int age,String Address){ this.name = name; this.age = age; this.Address = Address; } public void setName(String name){ this.name = name; } public void setAge(int age){ this.age = age; } public void setAddress(String Address){ this.Address = Address; } public String getName(){ return name; } public String getAddress(){ return Address; } public int getAge(){ return age; } public String toString(){ return ("Student name is "+this.getName()+", age is "+this.getAge()+", and address is "+this.getAddress()); } } public class JAVA3_Serialization { // when you implement Serializable then you must be write a serialVersionUId because when it serialise and deserialize it uniquely identify in the network // when u update ur object or anything then you have to update the serialVersionUId increment . // private static final long serialVersionUId = 1l; // transient int x ; // If you do not want a particular value to serialise and Deserialize. // the value x, when you don't serialise and Deserialize Then transient you used. public static void main(String[] args) { Student student = new Student("kanha",21,"angul odisha"); String filename = "D:\Advance JAVA\CLS3 JAVA\Test.txt"; // store the data in this location FileOutputStream fileOut = null; // write file ObjectOutputStream objOut = null; // create object //Serialization try { fileOut = new FileOutputStream(filename); objOut = new ObjectOutputStream(fileOut); objOut.writeObject(student); objOut.close(); fileOut.close(); System.out.println("Object has been serialise =\n"+student); } catch (IOException ex){ System.out.println("error will occure"); } //Deserialization FileInputStream fileIn = null; ObjectInputStream objIn = null; try { fileIn = new FileInputStream(filename); objIn = new ObjectInputStream(fileIn); Student object =(Student) objIn.readObject(); System.out.println("object has been Deserialization =\n"+object); objIn.close(); fileIn.close(); } catch (IOException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } }
✍ 重點:
▶️ 預設僅序列化非靜態和非瞬態資料成員。
▶️ 如果序列化後修改了類,可序列化物件必須確保版本之間的相容性。
如需更多見解,請隨時提及您的 GitHub 以獲取深入的範例和程式碼範例!如果您需要任何具體調整,請告訴我。
GitHub - https://github.com/Prabhanjan-17p
以上是Java 中的序列化與反序列化的詳細內容。更多資訊請關注PHP中文網其他相關文章!