@Deprecated 是 Java 標準註解,用於標記不再推薦使用的 API。但許多開發者誤以為它具備「繼承傳遞性」——即父類標註後,子類自動生效。本文實測驗證其實際行為,並說明 IDE 與編譯器的差異。
warning: [deprecation] ... has been deprecated@Deprecated
class Parent { public void doSomething() {} }
class Child extends Parent {
@Override public void doSomething() {} // 重寫父類方法
}
public class Test {
public static void main(String[] args) {
Child c = new Child();
c.doSomething(); // 編譯/IDE 是否警告?
}
}
| 場景 | javac 編譯器 | IntelliJ IDEA | Eclipse |
|---|---|---|---|
| 直接使用 Parent.doSomething() | ⚠️ 警告 | ⚠️ 警告 (劃線) | ⚠️ 警告 |
| 使用 Child.doSomething() (繼承未重寫) | ⚠️ 警告 | ⚠️ 警告 | ⚠️ 警告 |
| Child 重寫 doSomething() | ❌ 無警告 | ❌ 無警告 | ❌ 無警告 |
| Child 新增方法 newMethod() | ❌ 無警告 | ❌ 無警告 | ❌ 無警告 |
@Inherited 僅作用於類層級的註解查詢 (clazz.isAnnotationPresent()),不影響方法/欄位。@Deprecated,不遞歸檢查父類鏈。@Deprecated,子類重寫方法同樣加上@Deprecated,並用 @Override 確保確實重寫。@deprecated 說明替代方案、遷移時間表、移除版本,IDE 會顯示在工具提示中。jdeprscan 掃描專案,確認無意外殘留棄用調用。@Deprecated(since = "1.8", forRemoval = true)
public void oldMethod() { ... }
since:標明自哪版本棄用forRemoval=true:明確宣告將在未來版本移除,編譯器會給出更強烈警告
@Deprecated是「文檔級」警示,無繼承傳遞性,子類重寫會切斷警告鏈。團隊應建立「棄用必雙標、文檔必說明、工具必掃描」規範,確保 API 演進可控。