使い道もあるもんだ...
2008.12.01
というのは、Java 5 の新機能(遅ればせながらね)、static import です。地味だねえ...
要するに、クラス変数とかクラスメソッドが、クラス全部を import しなくても、「その変数だけ」で import できる機能です。こうやるだけですね。
import static jp.or.nurs.sug.Test.CONST_NO1;
とかね。そりゃ使えば使えちゃうモノだけど、
これを使うとホントに助かるコンテキスト
ってあるんだろうか、と結構?になっていたのですが、初めて、
あってよかった....
となった場面に遭遇しました。それはですね、
Constants という名前のクラスが、複数のパッケージにあって、双方とも static 変数を供給するためのクラスだったりします(ありがちな名前ですね)。ですから、両方を同時に import すると、クラス名がバッティングしてしまうので、じゃあ、両方とも FQCN で記述しないと....となるのですが、これが static import で回避できます。
import static sub2.Constants.ZERO;
import sub1.Constants;
public class Test {
public static void main( String [] args ) {
System.out.println( ZERO );
System.out.println( Constants.ONE );
}
}
この時、最初の ZERO は、static import された sub2.Constants の ZERO を指し、2番目の ONE は sub1.Constants の ONE を指します。ですから、使う度合いの少ない方を、変数名名指しで static import すれば良いわけですね。
さらに面白いのはコレです。
public static void main( String [] args ) {
System.out.println( ZERO );
System.out.println( Constants.ZERO );
}
ここで、最初の ZERO は static import された sub2.Constants.ZERO を、2番目の ZERO は普通に import された sub1.Constants.ZERO をうまく区別して指すか...というと指しました。ふう、うまく出来てます。static import は決して無駄じゃなかったですね!
もう少し背景に突っ込みましょうか。Java ではあまり強調されないことですが、実はクラス変数・クラスメソッドはまったくなしで済ますこと、というのはOOP言語では不可能なことじゃないのです。その場合どうやって数学関数とか import するのか....というと、実は
import なんてせずに、Math ライブラリ・クラスを継承しちゃう
というやり方をすればイイのです。勿論、クラス変数・クラスメソッドなしの世界を実現するためには、
多重継承ができないと、現実的ではない
のですけどね。言い換えると、static クラスを import して使う、ということは、
かなり弱いけども継承「のような」性格がある(static クラスを implements したらもう少し強いけども)
ことになります。クラス変数・クラスメソッドの場合、
インスタンスとは独立しており、上書き(override)はされずに、単純に隠蔽される
という仕様には、弱いながらも import や implements によって「多重継承みたいな」状況になったとしても、ホントの多重継承でややこしい問題になるいわゆる「名前の衝突」の問題に直面しなくても済む、というメリットがあったりするのです。
この多重継承で「名前の衝突」が起きた時、どっちかの名前を「改名」して衝突を回避する、っていう手法があります。自分の複数ある親クラスのメンバ名が偶然同じとき、どちらのクラスのメンバなのか区別できないので、それを継承の際のオプションとして「改名」しちゃう、という機能です。これは C++ にはないのですが、Eiffel にはあり(というかEiffel が参考にした非OOPLである Ada にも、「パッケージの継承」の機能があるので、やはり「改名」があります...)、Meyer が「オブジェクト指向入門」(第15章)で結構突っ込んだ議論をしてます。今遭遇した問題というのも、実はこういう「改名」が必要となるような「名前の衝突」の問題なんですよね。
C++ の場合は、類似の問題として菱形継承を回避するための、仮想継承という機能がありますが、これは基底クラスが共通しちゃった場合の対策ですから、Eiffel 流の改名の方が、やや広い問題(偶然の名前バッティング)に対処できることになるでしょう。そう見ると、実は
Java5 の static import は、FQCN でも改名するわけじゃないけども、別なコンテキストが導入できて、「改名みたい」な効果の得られる機能
という風に言えるかも知れませんね。
投稿者 : 杉浦 こずえ | 投稿日時 : 2008.12.01 21:46
あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。


