學生疑惑:static方法(Hide)與實例方法(Override)在內存中如何區別?為什麼static方法「不易改變」?
JVM通過不同的調用指令實現兩種語義:
| 特性 | Override(實例方法) | Hide(static方法) |
|---|---|---|
| 調用指令 | invokevirtual | invokestatic |
| 綁定時機 | 運行時動態綁定 | 編譯時靜態綁定 |
| 決策依據 | 對象實際類型 | 引用聲明類型 |
| 多態支持 | 支持 | 不支持 |
// 子類調用父類 static 方法:Hide
Parent.staticMethod(); // 字節碼:invokestatic Parent.staticMethod
// 子類調用父類實例方法:Override
parentRef.instanceMethod(); // 字節碼:invokevirtual Parent.instanceMethod
static方法與實例方法均存於此,無本質區別。invokestatic時,不傳遞this引用;invokevirtual需將對象引用壓棧,運行時解析實際方法表。invokevirtual通過索引查找實際實現,實現多態。因為invokestatic在編譯期確定目標方法,運行時不再查找。即使子類定義同名static方法,父類引用調用仍執行父類版本——這是靜態綁定特性,非內存存儲差異。
研讀《深入理解Java虛擬機》第8章「虛擬機字節碼執行引擎」,重點掌握invokevirtual、invokespecial、invokestatic、invokeinterface四條調用指令的語義差異。