首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java protected 存取權限深度解析:跨套件繼承的可見性陷阱

     編輯:Java 相關知識

核心規則

protected 成員對以下可見:

  1. 同一套件內的所有類別(同 default)。
  2. **不同套件的子類別**,但僅限於透過「子類別實例」存取。

經典陷阱範例

範例 1:同套件子類別可存取

// package pkg1
class MyObject2 {
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// package pkg1
public class Test2 {
    public static void main(String[] args) throws Exception {
        MyObject2 obj = new MyObject2();
        obj.clone(); // 編譯通過:同套件,protected 可見
    }
}

範例 2:不同套件子類別,嘗試存取父類別實例的 protected 成員 → 編譯錯誤

// package pkg1
class MyObject3 {
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// package pkg2
public class Test3 extends MyObject3 {
    public static void main(String[] args) throws Exception {
        MyObject3 obj = new MyObject3();
        obj.clone(); // ❌ 編譯錯誤:obj 是父類別實例,非子類別實例

        Test3 tobj = new Test3();
        tobj.clone(); // ✅ 編譯通過:tobj 是子類別實例
    }
}

規則權威來源

Java Language Specification / Java in a Nutshell:
"Suppose class A declares a protected field x and is extended by class B in a different package. Class B inherits x, and its code can access x in the current instance of B or any other instances of B. This does NOT mean B can access x in arbitrary instances of A!"

為什麼這麼設計?

  • 封裝性:父類別內部實現細節(protected 欄位/方法)不應被外部任意實例存取,即使是子類別也僅能存取「屬於子類別型別的物件」。
  • 防止脆弱基類:若子類別可隨意存取任意父類別實例的 protected 成員,父類別內部修改極易波及不知情的子類別。

常見誤解澄清

錯誤認知正確認知
protected = 同套件 + 所有子類別protected = 同套件 + 子類別自身實例
子類別可存取父類別任何實例的 protected 成員子類別僅能存取子類別型別實例的 protected 成員
覆寫後變 public 只是為了方便覆寫後改 public 是為了讓任意類別可呼叫(如 clone())

實務建議

  1. 極力減少 protected 欄位,改用 private + protected getter/setter。
  2. 若需提供給子類別覆寫的模板方法,使用 protected 方法而非欄位。
  3. 跨套件繼承時,記住「只能用 this./super. 存取,不能用 parentInstance.」。
  4. 閱讀英文原版規格書(JLS),中文教材常簡化導致誤解。

結語

protected 的跨套件可見性限制是 Java 封裝模型精心設計的結果。理解「子類別僅能存取子類別實例的 protected 成員」是避開編譯錯誤與設計缺陷的關鍵。建議開發者養成查閱 JLS 的習慣,建立精確的語言模型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved