| 修飾符 | 同一類別 | 同一套件 | 子類別(不同套件) | 非子類別(不同套件) |
|---|---|---|---|---|
| public | ✅ | ✅ | ✅ | ✅ |
| protected | ✅ | ✅ | ✅ | ❌ |
| default (無修飾符) | ✅ | ✅ | ❌ | ❌ |
| private | ✅ | ❌ | ❌ | ❌ |
// 父類別
package com.parent;
public class Parent {
protected int value = 100;
}
// 子類別 (不同套件)
package com.child;
public class Child extends Parent {
public void access() {
System.out.println(this.value); // ✅ 繼承的欄位,可直接存取
System.out.println(super.value); // ✅
Parent p = new Parent();
// System.out.println(p.value); // ❌ 編譯錯誤!非子類別實例不可存取
}
}
// 非子類別 (同套件)
package com.parent;
public class Neighbor {
public void test() {
Parent p = new Parent();
System.out.println(p.value); // ✅ 同套件可存取 protected
}
}
核心規則:protected 允許**子類別透過繼承**存取,以及**同套件任何類別**存取。**但子類別不能透過父類別實例引用存取 protected 成員** (除非同套件)。
| 修飾符 | 說明 |
|---|---|
| public | 任何地方可存取,一個 .java 檔只能有一個 public 類別,檔名必須同名 |
| default | 僅同套件可存取,檔名可任意 |
⚠️ 頂層類別不能用 protected/private (內部類別除外)。
private,提供 public getter/setterpublic,內部實作細節 privateprotecteddefaultprivate + protected getter/setter// module-info.java
module com.example.app {
exports com.example.api; // 公開 API 套件
// com.example.impl 不導出,僅模組內部可見
}
public 類別若在未導出套件,模組外**仍不可存取** (編譯/運行雙重檢查)opens 允許反射存取私有成員 (供框架如 Spring/Hibernate 用)public abstract (Java 8 前);Java 9+ 允許 private 方法public static finalprivate 用於單例/工廠模式掌握 public > protected > default > private 可見性遞減順序,理解 protected 的「繼承存取」與「套件存取」雙重語意,配合模組系統 (exports/opens) 實現**真正的強封裝**,是設計健壯 Java API 的基石。