許多開發者能熟練使用 API,卻對 Java 底層核心機制知其然不知所以然。本文深度剖析序列化、RTTI、回調、反射四大機制,揭示其原理、應用場景與最佳實踐,助你構建堅實的技術內功。
// 1. 實現 Serializable 標記接口(無方法)
public class User implements Serializable {
private static final long serialVersionUID = 1L; // 強烈建議顯式聲明
private String name;
private transient String password; // transient 跳過序列化
// getter/setter
}
// 2. 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {
oos.writeObject(user);
}
// 3. 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {
User u = (User) ois.readObject();
}
| 陷阱 | 後果 | 對策 |
|---|---|---|
| 無 serialVersionUID | 類變更導致 InvalidClassException | 顯式聲明,修改結構時手動更新 |
| 非 transient 靜態字段 | 靜態屬於類不屬於實例,不序列化 | 理解語義,勿依賴靜態字段持久化 |
| 父類未實現 Serializable | 反序列化時父類構造函數重新執行,字段重置 | 父類也實現 Serializable 或提供無參構造 |
| 單例被破壞 | 反序列化產生新實例 | 實現 readResolve() 返回單例實例 |
| 性能/體積差 | 默認二進制格式冗長、慢 | 考慮 Protobuf、Kryo、Jackson JSON、Hessian |
Class 對象:每個類加載時生成唯一 Class 實例,存儲類結構元數據。instanceof:運行時類型檢查,編譯器插入類型比較字節碼。Class.cast():動態類型轉換,失敗拋 ClassCastException。編譯期類型擦除(泛型)或面向介面編程導致具體類型未知時,RTTI 允許安全地發現並使用真實類型:
void process(List> list) {
for (Object obj : list) {
if (obj instanceof String) {
String s = (String) obj; // 安全轉換
} else if (obj.getClass() == Integer.class) { // 精確匹配
// ...
}
}
}
沒有 RTTI,介口、抽象類、父類引用將無法還原具體行為,多態失去意義。
主線程註冊監聽器/回調接口,子線程/事件源發生特定狀態時主動通知,主線程無需輪詢。
// 輪詢模式:資源浪費、延遲不可控
while (!task.isDone()) {
Thread.sleep(100);
}
result = task.getResult();
// 回調模式:事件驅動、即時響應
task.executeAsync(new Callback() {
@Override
public void onComplete(Result r) {
handleResult(r);
}
@Override
public void onError(Exception e) {
handleError(e);
}
});
Statement.setFetchSize()、Swing 事件監聽器、Servlet ServletContextListener。Future.get() 同步阻塞,CompletableFuture.thenApply() 異步鏈式回調。java.util.Observable/Observer(已棄用)、Guava EventBus、Spring ApplicationEvent。CompletableFuture、Reactor/RxJava 流式 API。Class.forName()、getMethods()、getFields()、getAnnotations()。clazz.newInstance()(棄用)、constructor.newInstance()。method.invoke()、field.set/get()、繞過訪問修飾符 setAccessible(true)。Proxy.newProxyInstance() 生成介口實現,AOP 基石。優化:緩存 Method/Field/Constructor、setAccessible(true)、關鍵路徑改用字節碼生成(ASM/ByteBuddy)。
| 機制 | 核心關鍵字 | 典型場景 | 底層依賴 |
|---|---|---|---|
| 序列化 | Serializable, serialVersionUID, transient | RMI、緩存、會話複製、深度克隆 | ObjectOutputStream/InputStream |
| RTTI | Class, instanceof, cast | 多態還原、類型安全檢查、反射前提 | JVM 類加載器、Class 對象 |
| 回調 | Interface, Future, CompletableFuture, Listener | 異步 IO、事件驅動、異步編程 | 線程池、內存屏障、函數式接口 |
| 反射 | Class, Method, Field, Constructor, Proxy | 框架開發、動態代理、熱加載、測試 | RTTI、安全管理器、字節碼操作 |
掌握這四大機制,不僅能讀懂主流框架源碼,更能在架構設計中遊刃有餘,寫出靈活、可擴展、高性能的 Java 系統。