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

Java 封裝核心:Getter/Setter 方法深度解析與實戰應用

     編輯:Java 程式設計入門

封裝核心原則

封裝是將資料(屬性)與操作資料的方法綁定,並對外隱藏內部實現細節。核心做法:

  1. 屬性私有化:使用 private 修飾符,禁止外部直接存取
  2. 提供公共存取器:getXxx() 取值、setXxx() 賦值
  3. 在存取器中加入控制邏輯:驗證、轉換、日誌、延遲初始化等

為什麼需要封裝?

標準 JavaBean 範例

public class Book {
    private int id;
    private String name;
    private double price;
    private String author;

    // 無參建構子(框架反射實例化必需)
    public Book() {}

    // 全參建構子(方便建立物件)
    public Book(int id, String name, double price, String author) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.author = author;
    }

    // Getter/Setter
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { 
        this.name = name != null ? name.trim() : null; // 防禦性處理
    }

    public double getPrice() { return price; }
    public void setPrice(double price) {
        if (price < 0) throw new IllegalArgumentException("價格不能為負數");
        this.price = price;
    }

    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
}

進階封裝模式

1. 唯讀屬性(不可變物件)

public final class ImmutablePoint {
    private final int x;
    private final int y;
    
    public ImmutablePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    public int getX() { return x; }
    public int getY() { return y; }
    // 無 setter,物件建立後狀態不可變
}

2. 延遲初始化

public class ExpensiveResource {
    private HeavyObject heavyObject;
    
    public HeavyObject getHeavyObject() {
        if (heavyObject == null) {
            synchronized (this) {
                if (heavyObject == null) { // 雙重檢查鎖
                    heavyObject = new HeavyObject();
                }
            }
        }
        return heavyObject;
    }
}

3. 防禦性複製

public class Period {
    private final Date start;
    private final Date end;
    
    public Period(Date start, Date end) {
        // 建構子防禦性複製
        this.start = new Date(start.getTime());
        this.end = new Date(end.getTime());
        if (this.start.compareTo(this.end) > 0)
            throw new IllegalArgumentException("開始時間不能晚於結束時間");
    }
    
    public Date getStart() {
        // Getter 防禦性複製,防止外部修改內部狀態
        return new Date(start.getTime());
    }
    
    public Date getEnd() {
        return new Date(end.getTime());
    }
}

IDE 自動生成技巧

  • Eclipse:Alt + Shift + S → Generate Getters and Setters
  • IntelliJ IDEA:Alt + Insert → Getter and Setter
  • 可勾選生成 toString()、equals()/hashCode()、建構子

常見誤區

優勢說明
資料保護防止無效/非法資料寫入(如年齡負數、空字串名稱)
實現隱藏內部儲存方式變更(如改用 Map、資料庫)不影響呼叫端
靈活控制可實現唯讀(僅 getter)、唯寫(僅 setter)、延遲載入
除錯便利在 setter 中設斷點/日誌,追蹤資料變更來源
框架相容JavaBean 規範、ORM、序列化、JSON 轉換均依賴 getter/setter
誤區正確認知
所有類別都要為每個屬性生成 getter/setterDTO/VO 需要,領域模型應暴露行為而非資料(告訴物件做什麼,別問物件有什麼)
setter 僅做單純賦值應包含驗證、轉換、副作用處理
回傳可變物件引用回傳副本或不可變視圖(Collections.unmodifiableList())
boolean 型屬性用 getXxx()慣例用 isXxx()(如 isActive())

Lombok 簡化封裝

@Data // 包含 @Getter @Setter @ToString @EqualsAndHashCode @RequiredArgsConstructor
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
    private Long id;
    private String username;
    private String email;
    
    @Setter(AccessLevel.NONE) // 唯讀,僅建構子設定
    private LocalDateTime createdAt;
}

編譯期自動生成標準存取器,減少樣板程式碼,但需理解其生成邏輯。

總結

封裝不只是「私有屬性 + getter/setter」,而是資料保護、實現隱藏、介面契約的綜合體現。良好的封裝讓類別成為堅固的模組,支援系統演進與維護。掌握防禦性複製、不可變模式、延遲初始化等進階技巧,能寫出更健壯的 Java 程式碼。

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