類別存取修飾符詳細解析
| 修飾符 | 同類 | 同包 | 子類(異包) | 非子類(異包) |
public | ✓ | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✓ | ✗ |
default (包私有) | ✓ | ✓ | ✗ | ✗ |
private | ✓ | ✗ | ✗ | ✗ |
類別層級存取控制
public class:所有地方可見,檔案名必須與類別名一致
default class:包私有,同包可見。一個 .java 檔案只能有一個 public 類別,可包含多個 default 類別
- 無
private/protected class(內部類別除外)
封裝三步驟實戰
步驟 1:屬性私有化
public class Dog {
private String name = "無名氏";
private int health = 100;
// 編譯器報錯:外部無法直接存取
// dog.name = "Lucky"; // 錯誤
}
步驟 2:生成標準 Getter/Setter
// Eclipse: Alt+Shift+S → Generate Getters and Setters
// IDEA: Alt+Insert → Getter and Setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getHealth() { return health; }
public void setHealth(int health) {
if (health < 0) health = 0;
if (health > 100) health = 100;
this.health = health; // 業務邏輯驗證
}
步驟 3:在存取器中加入控制邏輯
- 驗證:範圍檢查、非空檢查、格式驗證
- 轉換:字串修剪、大小寫統一、單位轉換
- 副作用:觸發事件、更新關聯物件、記錄審計日誌
- 延遲初始化:首次存取時建立昂貴資源
this 關鍵字核心用法
| 用法 | 說明 | 範例 |
| 區分同名變數 | 區分實例變數與區域/參數變數 | this.name = name; |
| 呼叫本類別建構子 | 建構子鏈,this(...) 必須首行 | this("預設名", 100); |
| 返回當前物件 | 鏈式呼叫/建構者模式 | return this; |
| 傳遞當前物件 | 作為參數傳給其他方法 | other.process(this); |
| 內部類別存取外部 | OuterClass.this | OuterClass.this.outerField |
建構子鏈實戰
public class Dog {
private String name;
private int health;
private String breed;
// 主建構子
public Dog(String name, int health, String breed) {
this.name = name;
this.health = health;
this.breed = breed;
}
// 便利建構子鏈向主建構子
public Dog(String name) {
this(name, 100, "混種"); // 必須第一行
}
public Dog() {
this("無名氏"); // 呼叫上一個建構子
}
}
程式碼格式化最佳實踐
- Eclipse:
Ctrl + Shift + F(英文輸入法下)
- IDEA:
Ctrl + Alt + L(重新格式化)
- 配置統一代碼風格:Google Java Style
- 整合
Spotless/Checkstyle 到 Maven/Gradle,CI 自動檢查
常見封裝反模式
| 反模式 | 問題 | 改進 |
| Anemic Domain Model (貧血模型) | 只有 getter/setter,業務邏輯在 Service | Rich Domain Model:封裝行為,dog.feed() 而非 dog.setHealth(dog.getHealth()+10) |
| 過度封裝 | 簡單 DTO 也加驗證,增加複雜度 | 分層設計:DTO 無邏輯,領域模型豐富封裝 |
| Getter 洩露內部集合 | return items; 允許外部修改 | return Collections.unmodifiableList(items); 或返回副本 |
| Setter 返回 void | 無法鏈式呼叫 | Builder 模式或 return this;(需權衡) |
進階:不可變物件模式
public final class ImmutableDog {
private final String name;
private final int health;
private final List tricks; // 可變物件需特殊處理
public ImmutableDog(String name, int health, List tricks) {
this.name = name;
this.health = health;
this.tricks = Collections.unmodifiableList(new ArrayList<>(tricks)); // 防禦性複製
}
// 僅 Getter,無 Setter
public String getName() { return name; }
public int getHealth() { return health; }
public List getTricks() { return tricks; } // 已是不可變視圖
// "修改" 返回新物件
public ImmutableDog withHealth(int newHealth) {
return new ImmutableDog(name, newHealth, tricks);
}
}
總結
封裝是面向物件設計的基石。掌握存取修飾符、標準 JavaBean 模式、this 用法、建構子鏈、不可變模式,並避開貧血模型、集合洩露等陷阱,能寫出高內聚、低耦合、易維護的 Java 程式碼。IDE 自動生成與格式化工具能大幅提升效率,但理解背後原理才是關鍵。
- 上一篇文章: HashMap 深度解析:核心原理、Put/Get 流程、哈希碼機制與最佳實踐
- 下一篇文章: Java 異常處理核心機制:Exception 體系、Try-Catch-Finally、自定義異常與面試高頻考點
Copyright ©
程式碼之家 All Rights Reserved