Javaにおいてgetter/setterは必要なのか?

2年半前ぐらいの話になるので少し記憶が曖昧なのですが、確か初心者向けのJavaの本に
「メンバ変数はprivateにしてgetter/setterを作れ」と書いてあったのを読んだ覚えがあります。それからはその通りにしていたのですが、だんだんとJavaに慣れていくにつれ「getter/setterは本当に必要なのか?」と思うようになりました。その後自分なりにいろいろと調べたり考えたりした結果、一つの結論にたどり着いたのでそれについて書こうと思います。

結論

まず結論から書きますが、必要な場合もあれば必要じゃない場合もあると思います。どっちだよ、と思った方もいると思いますがこれから解説していこうと思います。

必要な場合

①代入する値に制限をかけたいとき
②加工して値を渡したいとき
③読み取り専用にしたいとき
他にもあると思いますが、代表的なものはこの三つだと思います。それぞれ具体例を挙げて説明していこうと思います。

private int month;

public void setMonth(int month) {
    if (1 <= month && month <= 12) this.month = month;
    else throw new IllegalArgumentException();
}

public int getMonth() {
    return month;
}

月の変数が一番わかりやすいと思います。月なので、1~12以外の値が代入されたら困りますよね。そこでsetterでチェックすることで正しい値以外の代入を防ぐことができます。


private int id;

public void setId(int id) {
    this.id = id;
}

public String getId() {
    if (id < 10) return "0" + id;
    else "" + id;
}

ちょっとわかりにくいかもしれませんがIDをStringとして返す時に必ず2桁になるようにしています(この場合は普通にintで返してその後加工するのがいいような気もします)。


private int id;

public int getId() {
    return id;
}

setterを作らないことで読み取り専用にできます。ただこれはfinalを使っても全く同じことができるのでどっちを使うかは個人の好みですね。


以上が私の考える必要な場合です。

必要がない場合

これは一つだけだと思っていますが、そのまま値を代入したり返したりする場合です。

private int id;

public void setId(int id) {
    this.id = id;
}

public int getId(int id) {
    return id;
}

このようなgetter/setterだったらpublicでいいんじゃないかと思います。

まとめ

getter/setterは実装することでバグを防いだり便利になったりする場合も多くあると思います。しかし今までの例を見てもらえばわかると思いますが、ただ値を代入したり返したりするだけならいらないんじゃないかなー、というのが私の結論です。さらにgetter/setterが使われるようになった簡単な経緯についても調べてみましたがそれはおまけに書くので、とりあえず本文はここで終わりにしようと思います。読んでくださりありがとうございました。

おまけ

参考:
https://nagise.hatenablog.jp/entry/20141010/1412930502
https://www.eisbahn.jp/yoichiro/2014/10/java_property_for_gui.html

JBuilder2や3の頃(2000年前後?)にコーディングなしで視覚的にGUIを作れるようにしようとした結果JavaBeans規格が生まれ、その規格内でgetter/setterが使われていた、ということですね。その影響が強く今でも使われている、という説が強いらしいです。ただやはり完全にgetter/setterを使わない、というのは無理があると思いますし、私も上記のサイトに書かれていたこの言葉に共感します。

getter/setterは古いプログラミングスタイルのひとつの象徴かもしれない。しかし、それを捨て去るには、そもそもなぜそうしたのかを考える必要がある。なぜフェンスが立っているのかを知ることで初めてフェンスを撤去する決断が下せる。根拠もなくフェンスの中に飛び込むのは蛮勇でしかない。

コメントを残す