JavaBeans 是 Java 組件模型基石,其屬性設計遵循嚴格命名約定,支援構建工具的可視化組裝。本文系統闡述 Simple、Indexed、Bound、Constrained 四類屬性模式與 PropertyChange 事件機制,附完整代碼範例。
| 類型 | 定義 | 方法模式 | 典型場景 |
| Simple | 單一值屬性 | getX()/setX() 或 isX()/setX() (boolean) | 名稱、狀態、配置參數 |
| Indexed | 有序集合/數組 | getX(int i)/setX(int i, T val) + getX()/setX(T[]) | 列表、表格數據、多值屬性 |
| Bound | 變更需通知監聽器 | Simple 模式 + add/removePropertyChangeListener | UI 綁定、模型同步、配置熱更新 |
| Constrained | 變更可被否決 | Bound 模式 + add/removeVetoableChangeListener + setX() throws PropertyVetoException | 不可變約束、業務規則驗證、事務性屬性 |
代碼範例:Bound 屬性完整實現
public class PersonBean implements Serializable {
private String name = "Unknown";
private final PropertyChangeSupport changes = new PropertyChangeSupport(this);
public String getName() { return name; }
public void setName(String newName) {
String oldName = this.name;
this.name = newName;
// 觸發屬性變更事件:屬性名、舊值、新值
changes.firePropertyChange("name", oldName, newName);
}
// 構建工具註冊監聽器的標準介面
public void addPropertyChangeListener(PropertyChangeListener l) {
changes.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
changes.removePropertyChangeListener(l);
}
}
Constrained 屬性:可否決的變更
public void setAge(int newAge) throws PropertyVetoException {
int oldAge = this.age;
// 觸發否決檢查
changes.fireVetoableChange("age", oldAge, newAge);
this.age = newAge; // 無否決才真正賦值
changes.firePropertyChange("age", oldAge, newAge);
}
監聽器實現 VetoableChangeListener,在 vetoableChange() 中拋出 PropertyVetoException 即可阻止變更。
設計工具整合要點
- BeanInfo 類(可選)提供圖示、屬性描述符、事件集描述符,增強可視化編輯體驗。
- 屬性編輯器(PropertyEditor)支援複雜類型(顏色、字體、日期)在屬性表中編輯。
- 持久化:
java.beans.XMLEncoder/Decoder 可將 Bean 圖序列化為 XML,適合配置存儲。
最佳實踐
- 屬性名與方法名嚴格對應(大小寫敏感),構建工具依靠內省發現屬性。
- Bound/Constrained 事件源委託給
PropertyChangeSupport,線程安全、標準化。
- 不可變屬性僅提供
getter,構造器注入,避免多線程競態。
- 大量屬性變更考慮批量通知或延遲觸發,減少 UI 重繪風暴。
掌握 JavaBeans 規範,不僅能編寫工具友好的組件,更能深入理解 Spring Bean、JSF Managed Bean 等現代框架組件模型的設計淵源。
- 上一篇文章: 成為更優秀程序員的 10 個核心習慣:從防禦性編程到持續交付價值
- 下一篇文章: SWT 入門實戰:用 Java 調用原生圖形庫構建高性能 GUI
Copyright ©
程式碼之家 All Rights Reserved