torutkのブログ

ソフトウェア・エンジニアのブログ

Beansでプロパティの変更通知失敗コーディング

原因が分かってしまえば他愛もないコーディングミスなのですが、数時間はまってしまいました。
Beansのバウンドプロパティを実装し、プロパティ"level"が更新されたら通知するものです。

class MyBean extends AbstractBean implements Runnable {
    :
    public void setLevel(int aLevel) {
        int oldLevel = level;
        level = aLevel;
        firePropertyChange("level", oldLevel, level);
    }

    public void run() {
        setLevel(++level);  // levelをインクリメントし通知させるつもり
    }

    private int level;
}

タイマーで定期的にrun()を呼ぶことでlevelが増えていくのですが、一向に通知が発生せず数時間はまりました。(おかげで、BeansBindingのコードにログを埋めまくり・・・。)

最初++levelでインクリメントするコードだったのを、バウンドプロパティで通知するためにsetLevelメソッドを呼ぶようにしたのですが、それが落とし穴でした。

教訓

getter・setterメソッド中のコードを除き、フィールドを直接アクセスしてはいけない。

コンストラクタ中でフィールドを直接アクセスするのは?

厳格に教訓に従うならば、コンストラクタ中でもsetterメソッドを使用します。その場合、コンストラクタ中から非finalなメソッドを呼び出すのはよろしくないので、setterメソッドをfinalにします。