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

Java 成員變數與方法訪問權限詳解:public/protected/default/private 四大修飾符實戰對比

     編輯:Java 相關知識

Java 封裝的核心在於**訪問權限控制**。本文通過一個**跨包、繼承、同類**的完整測試矩陣,系統對比 public、protected、default (package-private)、private 四大修飾符對**成員變數**與**成員方法**的可見性差異,附完整可編譯測試代碼與「誰能訪問誰」速查表,徹底解決權限困惑。

測試場景設計

  • 基礎類: Base 定義四種權限的變數 i1~i4 與方法 m1()~m4()。
  • 同包子類: SubSamePkg extends Base。
  • 同包非子類: OtherSamePkg。
  • 異包子類: SubDiffPkg extends Base (在 other.pkg)。
  • 異包非子類: OtherDiffPkg (在 other.pkg)。

完整測試代碼(單檔案多類,便於複製執行)


// 檔案:AccessTest.java
package access;

public class Base {
    public int i1 = 1; int i2 = 2; protected int i3 = 3; private int i4 = 4;
    public void m1() {} void m2() {} protected void m3() {} private void m4() {}
}

class SubSamePkg extends Base {
    void test() {
        System.out.println(i1); System.out.println(i2); System.out.println(i3); // System.out.println(i4); // 編譯錯誤
        m1(); m2(); m3(); // m4(); // 編譯錯誤
    }
}

class OtherSamePkg {
    void test(Base b) {
        System.out.println(b.i1); System.out.println(b.i2); System.out.println(b.i3); // b.i4 錯誤
        b.m1(); b.m2(); b.m3(); // b.m4() 錯誤
    }
}

// 異包類需放在 other/pkg 目錄下,此處模擬說明
/*
package other.pkg;
import access.Base;
public class SubDiffPkg extends Base {
    void test() {
        System.out.println(i1); // System.out.println(i2); // default 不可見
        System.out.println(i3); // System.out.println(i4); // private 不可見
        m1(); // m2(); // default 不可見
        m3(); // m4(); // private 不可見
    }
}
public class OtherDiffPkg {
    void test(Base b) {
        System.out.println(b.i1); // b.i2 錯誤, b.i3 錯誤, b.i4 錯誤
        b.m1(); // b.m2() 錯誤, b.m3() 錯誤, b.m4() 錯誤
    }
}
*/

public class AccessTest {
    public static void main(String[] args) {
        Base b = new Base();
        System.out.println("=== 同包非子類訪問 Base 實例 ===");
        System.out.println(b.i1); System.out.println(b.i2); System.out.println(b.i3); // b.i4 不可見
        b.m1(); b.m2(); b.m3(); // b.m4() 不可見

        System.out.println("\n=== 同包子類內部訪問繼承成員 ===");
        new SubSamePkg().test();

        System.out.println("\n=== 異包子類/非子類:請移至 other.pkg 執行 ===");
    }
}

訪問權限速查表(綠=可見,紅=不可見)

修飾符同類同包子類同包非子類異包子類異包非子類
public✅✅✅✅✅
protected✅✅✅✅ (繼承)❌
default✅✅✅❌❌
private✅❌❌❌❌

關鍵規則口訣

  • public: 普天之下皆可見。
  • protected: 同包 + 異包**子類**(繼承鏈)可見;異包非子類不可見。
  • default: **僅同包**可見(無關繼承)。
  • private: **僅同類**可見(連子類都不可見)。

常見誤區澄清

  1. 「protected 等於 default + 子類」: ✅ 正確,但注意**異包子類只能通過繼承訪問**,不能通過父類實例訪問 parent.protectedField。
  2. 「介面方法默認 public」: ✅ Java 8 前介面方法隱含 public abstract;Java 9+ 允許 private 靜態/實例方法。
  3. 「外部類不能 private」: ✅ 頂層類只能 public 或 default;內部類可用四種修飾符。
  4. 「建構子可繼承」: ❌ 建構子不參與繼承,但子類建構子隱式/顯式呼叫 super()。

最佳實踐建議

  • ✅ **成員變數盡量 private**,提供 public/protected Getter/Setter(封裝)。
  • ✅ **方法預設 private**,需要時再放寬至 protected (供子類擴展) 或 public (對外 API)。
  • ✅ **包設計聚合相關類**,善用 default 實現包級協作,減少 public 暴露面。
  • ✅ 使用 **ArchUnit / Checkstyle** 自動化檢查權限規範(如禁止 public 欄位)。

熟練掌握四大權限修飾符的邊界,是寫出高內聚、低耦合、安全可控 Java 代碼的基石。

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