TOP > プログラマ2.0日報 > 使い道もあるもんだ...

あすなろBlogger

このエントリーを含むはてなブックマーク このエントリーをはてなブックマークに追加 この記事をクリップ! livedoorclip ユーザー数 BuzzurlにブックマークBuzzurlにブックマーク この記事をtweetする

使い道もあるもんだ...

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 が参考にした非OOPLである Ada にも、「パッケージの継承」の機能があるので、やはり「改名」があります...)、 が「オブジェクト指向入門」(第15章)で結構突っ込んだ議論をしてます。今遭遇した問題というのも、実はこういう「改名」が必要となるような「名前の衝突」の問題なんですよね。

C++ の場合は、類似の問題として菱形継承を回避するための、仮想継承という機能がありますが、これは基底クラスが共通しちゃった場合の対策ですから、Eiffel 流の改名の方が、やや広い問題(偶然の名前バッティング)に対処できることになるでしょう。そう見ると、実は

Java5 の static import は、FQCN でも改名するわけじゃないけども、別なコンテキストが導入できて、「改名みたい」な効果の得られる機能

という風に言えるかも知れませんね。

投稿者 : 杉浦 こずえ | 投稿日時 : 2008.12.01 21:46

あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。

トラックバックURL


コメントの送信








関連記事

カレンダー

<< 2008年12月 >>

  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

最新のエントリー

最新のトラックバック

最新のコメント

Tag

バックナンバー