物件序列化是將記憶體中的物件轉換為位元組流或文字格式,以便持久化儲存或網路傳輸;反序列化則是逆向還原。Java 內建提供預設序列化機制,但輸出為二進位格式,難以跨語言交互。Jackson 庫則提供高效能的 JSON 序列化支援,廣泛用於現代微服務與 REST API。本文同時示範兩種方式的完整用法。
java.io.Serializable 介面serialVersionUID 確保版本相容ObjectOutputStream output = new ObjectOutputStream(
new FileOutputStream("object.dat"));
output.writeObject(myObject);
output.close();
ObjectInputStream input = new ObjectInputStream(
new FileInputStream("object.dat"));
MyClass obj = (MyClass) input.readObject();
input.close();
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new File("object.json"), myObject);
MyClass obj = mapper.readValue(new File("object.json"), MyClass.class);
import java.io.*;
import java.util.ArrayList;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
public class Zoo implements Serializable {
private static final long serialVersionUID = 1L;
private static final ObjectMapper mapper = new ObjectMapper();
public static int maxAnimalCount;
public ArrayList<String> animals = new ArrayList<>();
public void addAnimal(String name) {
if (animals.size() < maxAnimalCount) animals.add(name);
}
@Override public String toString() {
return "Zoo:\n animals: " + animals + "\n maxAnimalCount: " + maxAnimalCount;
}
// 預設序列化
public void serializeToLog(String path) {
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path))) {
out.writeObject(this);
} catch (IOException e) { e.printStackTrace(); }
}
// JSON 序列化
public void serializeJSONToLog(String path) {
try { mapper.writeValue(new File(path), this); }
catch (IOException e) { e.printStackTrace(); }
}
// 預設反序列化
public static Zoo deserializeFromLog(String path) {
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(path))) {
return (Zoo) in.readObject();
} catch (Exception e) { e.printStackTrace(); return null; }
}
// JSON 反序列化
public static Zoo deserializeJSONFromLog(String path) {
try { return mapper.readValue(new File(path), Zoo.class); }
catch (IOException e) { e.printStackTrace(); return null; }
}
public static void main(String[] args) {
Zoo zoo1 = new Zoo(); Zoo.setMax(100);
zoo1.addAnimal("hamster"); zoo1.addAnimal("sheep");
zoo1.serializeToLog("zoo1.log");
zoo1.serializeJSONToLog("zoo1.json");
Zoo zoo2 = new Zoo(); Zoo.setMax(200);
zoo2.addAnimal("tiger");
zoo2.serializeToLog("zoo2.log");
Zoo.setMax(300); // 靜態欄位不會被序列化
zoo1 = Zoo.deserializeFromLog("zoo1.log");
zoo2 = Zoo.deserializeFromLog("zoo2.log");
System.out.println("zoo1: " + zoo1);
System.out.println("zoo2: " + zoo2);
zoo1 = Zoo.deserializeJSONFromLog("zoo1.json");
System.out.println("zoo1 from JSON: " + zoo1);
}
}
| 特性 | 預設序列化 | Jackson JSON |
|---|---|---|
| 格式 | 二進位 | 文字 |
| 跨語言 | 困難 | 原生支援 |
| 靜態欄位 | 不序列化 | 不序列化 |
| 版本演進 | 需手動維護 serialVersionUID | 支援 @JsonIgnoreProperties 等註解彈性處理 |
| 效能 | 較快 | 高效能,適合高併發 |
建議:系統內部 RPC、暫存可用預設序列化;對外 API、設定檔、日誌、異構系統整合請採用 JSON。