調用反序列化 API 時拋出異常提示「未定義構造方法」,但 API 文檔顯示該類明明有構造函數。截圖顯示類繼承自 Dictionary 並實現了 ISerializable 接口。
當類(或其父類)實現 ISerializable 接口時,**啟用了自定義序列化機制** 。此模式下,反序列化**強制要求**類提供特定簽名的「序列化構造函數」:
// 必須簽名(C# 語法,Java 類似機制)
protected MyClass(SerializationInfo info, StreamingContext context) {
// 從 info 獲取數據還原字段
this.field = info.GetInt32("fieldName");
}
普通構造函數(無參/帶業務參數)**不滿足**反序列化引擎的調用約定,因此報「找不到構造方法」。
protected 或 private):// Java 對應:實現 Serializable 時可選實現 readObject
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject(); // 或手動讀取字段
// 邏輯處理...
}
GetObjectData / writeObject 輸出數據:// Java 對應
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject(); // 或手動寫入字段
}
import java.io.*;
public class MyClass implements Serializable {
private int id;
private String name;
// 瞬態字段不參與序列化
private transient String cache;
// 普通構造函數
public MyClass(int id, String name) { ... }
// 自定義反序列化(可選,若需特殊邏輯)
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
// 額外初始化 cache 等
}
// 自定義序列化(可選)
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
}
Serializable 就萬事大吉 → 忽略了父類鏈中可能已實現 ISerializable/Externalizable。public → 安全風險,規範要求非公有。serialVersionUID → 導致 InvalidClassException。readObject/writeObject(Java)或序列化構造函數(C#)。private static final long serialVersionUID = 1L; 鎖定版本。ObjectInputStream 重寫 resolveClass 或使用替代序列化庫(Jackson/Kryo)。理解「標準序列化」與「自定義序列化」的區別,按協議補全必要方法,即可解決此類報錯。