- Offer來了:Java面試核心知識點精講(原理篇)
- 王磊
- 1041字
- 2020-04-03 12:50:10
2.7 序列化
Java對象在JVM運行時被創建、更新和銷毀,當JVM退出時,對象也會隨之銷毀,即這些對象的生命周期不會比JVM的生命周期更長。但在現實應用中,我們常常需要將對象及其狀態在多個應用之間傳遞、共享,或者將對象及其狀態持久化,在其他地方重新讀取被保存的對象及其狀態繼續進行處理。這就需要通過將Java對象序列化來實現。
在使用Java序列化技術保存對象及其狀態信息時,對象及其狀態信息會被保存在一組字節數組中,在需要時再將這些字節數組反序列化為對象。注意,對象序列化保存的是對象的狀態,即它的成員變量,因此類中的靜態變量不會被序列化。
對象序列化除了用于持久化對象,在RPC(遠程過程調用)或者網絡傳輸中也經常被使用。
2.7.1 Java序列化API的使用
Java序列化API為處理對象序列化提供了一個標準機制,具體的Java系列化需要注意以下事項。
◎ 類要實現序列化功能,只需實現java.io.Serializable接口即可。
◎ 序列化和反序列化必須保持序列化的ID一致,一般使用private static final long serialVersionUID定義序列化ID。
◎ 序列化并不保存靜態變量。
◎ 在需要序列化父類變量時,父類也需要實現Serializable接口。
◎ 使用Transient關鍵字可以阻止該變量被序列化,在被反序列化后,transient變量的值被設為對應類型的初始值,例如,int類型變量的值是0,對象類型變量的值是null。
具體的序列化實現代碼如下:
import java.io.Serializable; //通過實現Serializable接口定義可序列化的Worker類 public class Wroker implements Serializable { //定義序列化的ID private static final long serialVersionUID = 123456789L; //name屬性將被序列化 private String name; //transient修飾的變量不會被序列化 private transient int salary; //靜態變量屬于類信息,不屬于對象的狀態,因此不會被序列化 static int age =100; public String getName() { return name; } public void setName(String name) { this.name = name; } }
以上代碼通過implements Serializable實現了一個序列化的類。注意,transient修飾的屬性和static修飾的靜態屬性不會被序列化。
對象通過序列化后在網絡上傳輸時,基于網絡安全,我們可以在序列化前將一些敏感字段(用戶名、密碼、身份證號碼)使用秘鑰進行加密,在反序列化后再基于秘鑰對數據進行解密。這樣即使數據在網絡中被劫持,由于缺少秘鑰也無法對數據進行解析,這樣可以在一定程度上保證序列化對象的數據安全。
2.7.2 序列化和反序列化
在Java生態中有很多優秀的序列化框架,比如arvo、protobuf、thrift、fastjson。我們也可以基于JDK原生的ObjectOutputStream和ObjectInputStream類實現對象進行序列化及反序列化,并調用其writeObject和readObject方法實現自定義序列化策略。具體的實現代碼如下:
public static void main(String[] args) throws Exception { //序列化數據到磁盤 FileOutputStream fos = new FileOutputStream("worker.out"); ObjectOutputStream oos = new ObjectOutputStream(fos); Wroker testObject = new Wroker(); testObject.setName("alex"); oos.writeObject(testObject); oos.flush(); oos.close(); //反序列化磁盤數據并解析數據狀態 FileInputStream fis = new FileInputStream("worker.out"); ObjectInputStream ois = new ObjectInputStream(fis); Wroker deTest = (Wroker) ois.readObject(); System.out.println(deTest.getName()); }
以上代碼通過文件流的方式將wroker對象的狀態寫入磁盤中,在需要使用的時候再以文件流的方式將其讀取并反序列化成我們需要的對象及其狀態數據。
- Redis入門指南(第3版)
- Learning Docker
- Python進階編程:編寫更高效、優雅的Python代碼
- 琢石成器:Windows環境下32位匯編語言程序設計
- 小程序開發原理與實戰
- 大學計算機基礎實驗指導
- Java EE 8 Application Development
- C語言程序設計實驗指導 (第2版)
- C和C++游戲趣味編程
- IBM Cognos Business Intelligence 10.1 Dashboarding cookbook
- 從程序員角度學習數據庫技術(藍橋杯軟件大賽培訓教材-Java方向)
- Mastering JavaScript
- Python 3快速入門與實戰
- LabVIEW入門與實戰開發100例(第4版)
- 川哥教你Spring Boot 2實戰