Headline About TechLog Download Java VBA Link


June 14, 2007. Thursday.

Javaの格言:public変数は使うな!

javaに詳しい人間なら「何を言っているんだこいつは」と思うような一言。そう思う人は早々に読み飛ばして下さい。しかしこれは重要な話。果たして普段のコーディングにおいて、どの程度public変数を利用する必然性があるでしょうか。例えばbaristaが以前行なったプロジェクトにおいて、static finalではない変数は全てprivateでした。初心者はこの一行だけ読んで後は読まなくてもかまいません。


変数は全部privateにする事。



System.out.println("test");

Sunのコードの中で一番有名なpublic変数といえばこのoutでしょう。その他にはPointクラスのxやyなどもそうです。共通するのは、頻繁にアクセスする上でgetXXX()などといちいちやるのが面倒、と言うところでしょうか。



オブジェクト指向であるJavaではカプセル化を意識し、変数をprivateとし、getter、setterでアクセスするよう設計するのが普通です。コーディング規約中には以下のように記述されています。対訳はbaristaによる意訳ですので参考程度に。

 Don't make any instance or class variable public without good reason. Often, instance variables don't need to be explicitly set or gotten-often that happens as a side effect of method calls.

 マトモな理由無しにインスタンス変数やクラス変数をpublicにしないこと。大抵の場合、インスタンス変数は明示的に設定するものではなく、処理の過程で値がget/setされるものです。

例えばBaristaクラスを作った場合、インスタンス変数weightをpublicにして外から操作する設計はおかしい、という事。eat()を呼ぶと副作用としてweightが増え、drink()を呼ぶと副作用としてweightが増え、run()を呼ぶと副作用としてweightが減るけど連動してdrink()が呼ばれてweightが増える、という設計が普通でしょ?という説明です。直接weightが操作できるなんて、現実に即しません(笑)。



また、続いてこんな説明文があります。

 One example of appropriate public instance variables is the case where the class is essentially a data structure, with no behavior. In other words, if you would have used a struct instead of a class (if Java supported struct), then it's appropriate to make the class's instance variables public.

 インスタンス変数をpublicにしても良い例の一つは、classが処理の無いデータ構造体とみなせる場合です。言い換えるなら(もしJavaが構造体をサポートしてたとして)、そのクラスを構造体として書き換えられるなら、インスタンス変数をpublicにしてもよい。

さっきのPointクラスのx, yが上記に当りますね。


さて、果たしてこのような設計をする機会が初心者にあるでしょうか?恐らく無い。Pointクラスのような、構造体的データクラスなら作る可能性があるかもしれませんが。DBアクセス時に作成するDOクラスなどがその一例。しかし、そうしたクラスですら通常はsetterとgetterを使うのが普通です。



これまでの文章の意味があまり良くわからないなあ、と言う人は全ての変数をprivateにしてしまいましょう。どうしてもpublic変数を作るのならjavadocに「どんな理由でpublicにしたから、どういうところに気をつけてアクセスしなさい」と書く癖を付けましょう。上手く説明ができなかったら即privateに変更して下さい。