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

Java 訪問控制符詳解:四級權限矩陣、封裝最佳實踐與模塊化邊界

     編輯:Java 相關知識

四大訪問級別

修飾符同類同包子類(異包)非子類(異包)典型用途
public✓✓✓✓API 公開契約、介面方法
protected✓✓✓✗子類覆寫/模板鉤子、包內+繼承體系共享
default(包私有)✓✓✗✗模塊內部實現類、包級工具、SPI 實現類
private✓✗✗✗內部實現細節、字段封裝、輔助方法

適用目標範圍

目標可用修飾符說明
頂層類/介面public / default同一源文件僅一 public 類,文件名匹配
成員字段四種皆可規範:private + getter/setter
構造器四種皆可private 防實例化/單例;protected 限制繼承
成員方法四種皆可按契約暴露
局部變量不可用作用域由代碼塊決定

封裝最佳實踐:字段私有 + 存取器

public class Student {
    private int age;      // 字段私有
    private String id;
    
    public int getAge() { return age; }
    
    public void setAge(int age) {
        if (age < 0 || age > 150) 
            throw new IllegalArgumentException("Invalid age");
        this.age = age;
    }
    
    public String getId() { return id; }
    public void setId(String id) {
        if (id == null || !id.matches("\\d{10}"))
            throw new IllegalArgumentException("Invalid ID");
        this.id = id;
    }
}
  • 控制權:校驗邏輯集中在 setter,防止非法狀態。
  • 可維護性:內部存儲變更(如 int→Long、拆分字段)不影響調用者。
  • 只讀/寫控制:僅提供 getter → 不可變;僅 setter → 寫入-only(罕見)。
  • IDE 生成:Eclipse Alt+Shift+S→R, IntelliJ Alt+Insert→Getter/Setter。

進階封裝模式

1. 防實例化 + 防繼承(工具類標準)

public final class StringUtils {
    private StringUtils() {}  // private 構造器:不可 new、不可 extends
    public static boolean isBlank(String s) { ... }
}

2. 包私有實現類(SPI/模塊邊界)

// com.myapp.dao.UserDao.java (public 介面)
public interface UserDao { User findById(Long id); }

// com.myapp.dao.impl.UserDaoImpl.java (default 類)
class UserDaoImpl implements UserDao {  // 無 public,包外不可見
    public User findById(Long id) { ... }
}

// com.myapp.dao.DaoFactory.java (public 工廠)
public class DaoFactory {
    public static UserDao createUserDao() { return new UserDaoImpl(); }
}

調用方僅依賴介面+工廠,實現類可隨時替換,編譯期強制隔離。

3. protected 模板方法鉤子

public abstract class AbstractParser {
    // 子類可覆寫,包外不可直接調用
    protected void preProcess() { }  
    protected void postProcess() { }
    
    public final String parse(String input) {
        preProcess();
        String result = doParse(input);
        postProcess();
        return result;
    }
    protected abstract String doParse(String input);
}

模塊化系統中的訪問控制(JDK 9+ JPMS)

module-info.java 導出包:

module com.myapp.core {
    exports com.myapp.api;        // 公開 API 包
    exports com.myapp.spi;        // 公開 SPI 介面
    // com.myapp.internal 不導出 → 內部實現強封裝
    // 即使類是 public,模塊外也不可訪問(反射需 opens)
}
  • JPMS 在類訪問控制之上增加模塊級邊界。
  • public 類若所在包未 exports,模塊外不可用。
  • opens 允許反射深度訪問(框架如 Spring/Hibernate 需要)。

常見錯誤與重構建議

錯誤模式問題重構
字段 public破壞封裝,無法校驗、追蹤、遷移private + getter/setter
方法過度 public洩露內部邏輯,擴大耦合面縮小至 protected/default/private
構造器 public 工具類允許無意義實例化private 構造器 + final 類
測試代碼訪問 private破壞封裝邊界同包測試類用 default;或反射(setAccessible(true))

訪問控制設計原則

  1. 最小權限原則:默認 private,按需放寬。
  2. 面向介面編程:對外暴露 public interface,實現類 default 或 package-private。
  3. 繼承設計:預留給子類的用 protected,內部實現用 private。
  4. 模塊邊界:JPMS exports 精確控制包級可見性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved