首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java IO 進階(五):對象流與序列化機制詳解

     編輯:Java 相關知識

核心概念

  • 對象流:ObjectOutputStream / ObjectInputStream,直接讀寫 Java 對象
  • 序列化:對象 → 字節流 (持久化/網絡傳輸)
  • 反序列化:字節流 → 對象

序列化前提

  • 類實現 java.io.Serializable 標記接口 (無方法)
  • 所有非 transient 字段必須可序列化 (基本類型、String、實現 Serializable 的對象)
  • 建議顯式聲明 private static final long serialVersionUID = 1L; 避免版本不兼容導致 InvalidClassException

關鍵字 transient

  • 修飾字段:序列化時**忽略該字段**
  • 反序列化後該字段恢復為**默認值** (數值 0、引用 null、boolean false)
  • 適用場景:敏感數據 (密碼)、運行時上下文 (連接句柄、線程)、衍生字段 (可從其他字段計算)

Externalizable 接口 (完全控制)


public class MyData implements Externalizable {
    private int id;
    private String name;
    @Override public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(id);
        out.writeUTF(name);
    }
    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        id = in.readInt();
        name = in.readUTF();
    }
}

優點:自定義二進制格式、加密、壓縮、版本兼容邏輯。缺點:維護成本高,通常 Serializable 足夠。

完整示例


class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    int age = 25;
    String name = "Bob";
    transient String password = "secret"; // 不序列化
    String school = "MIT";
}

public class ObjectStreamDemo {
    public static void main(String[] args) throws Exception {
        // 序列化
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.dat"))) {
            oos.writeObject(new Student());
        }
        // 反序列化
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student.dat"))) {
            Student s = (Student) ois.readObject();
            System.out.println(s.age + " " + s.name + " " + s.password + " " + s.school);
            // 輸出: 25 Bob null MIT
        }
    }
}

注意事項

  • 靜態字段 不屬於對象狀態,不參與序列化
  • 父類未實現 Serializable 但子類實現:反序列化時父類調用無參構造初始化
  • 集合類 (ArrayList, HashMap) 已實現 Serializable,可直接序列化
  • 序列化破壞單例:需實現 readResolve() 返回實例
  • 跨 JVM 版本兼容:嚴格管理 serialVersionUID
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved