一度も使ったことがない JDK 5.0 の機能について、せめてサンプル的にソースコードを書いてみた。
Java SE 6 も出たことだし……
型保証された列挙
この機能のおかげで、enum という変数名は使えなくなってしまった。
Enumerator enum = ... ってコードをよく書いていたので、Java5環境に移行すると大変。
package java5.typeofenum;
////////////////////////////////////////////////////////////
// Type of Enum (列挙型)
public enum Products { // Ref. java.lang.Enum
BLENDED, BOOK, DVD,
}
メタデータ (注釈)
コードを堅牢にするメタデータ。
というヒント情報としての使い方をするのだと思っていたけど、
そのまま他の用途で使えたりもするらしい。
package java5.metadata;
public class Metadata{
////////////////////////////////////////////////////////////
// Metadata (アノテーション)
public static void doits(){
Parent p = new Parent();
Parent c = new Child();
p.doit();
c.doit();
}
public static class Parent{
public void doit(){
System.out.println("A parent does it.");
}
}
public static class Child extends Parent{
// 親クラスのメソッドをオーバーライドしていることを示すアノテーション
@Override public void doit(){
System.out.println("A child does it.");
}
}
}
static のインポート
static メンバにアクセスするには、そのメンバのクラスで参照を修飾する必要があります。たとえば次のようにしなければなりません。
double r = Math.cos(Math.PI * theta);
この状況を回避するため、static メンバをインタフェースに置いて、そのインタフェースから継承させることがあります。しかし、これは良い方法ではありません。実際、「Constant Interface Antipattern (不変のインタフェースアンチパターン)」であると以前から指摘され続けています。「Effective Java」の第 17 項を参照してください。問題は、クラスが別のクラスの static メンバを使用するのは、実装のほんのわずかな部分だということです。クラスがインタフェースを実装すると、そのインタフェースはそのクラスの公開 API の一部となります。実装の詳細は、公開 API として公開するべきではありません。
JDK 5.0 ドキュメント - static のインポート
Effective Java 17項 を読んだけど、なんかいまいち消化不良。
「型を定義するためだけにインターフェースを使用する」Constant Interface Antipattern (不変のインタフェースアンチパターン)。これをすると、クラスのメンバ定数を手軽にメンバ定数名だけで利用するには HogeClass implements HogeConstantInterface しなくちゃいけない。すると、そのクラス HogeClass の public なメンバ定数として他のクラスには見えてしまう。困る。
だから、interface のメンバ定数じゃなくて、(Math.PI みたいな)クラスのメンバ定数を使って、
private static final PI = Math.PI;
って書いておいて、private 定数を使え、と。
private static final PI = HogeConstantInterface.PI;
でも良いような気がするけど、
interface だと、ついうっかり implements できちゃう (もともと implements するためのものだから) ことがマズいという話なのかな。
で、ここまでは Java 5 より前の話で、
Java 5 のスタティック・インポートという新機能を使うと、クラスの static メンバを参照する際に「メンバ名」を記述するだけで良い。
もう、危なっかしい implements HogeConstantInterface よりも、こっちのほうがオススメですよ、と。
難しいことはあまり考えたくないので、
「お気ラクに定数を使える機能」ということで納得しておこう。
package java5.staticimport;
////////////////////////////////////////////////////////////
// Static import
import static java5.typeofenum.Products.*; // 列挙型のインポート
import static java5.metadata.Metadata.doits; // クラス・メソッドのインポート
public class StaticImport {
public static void main(String[] args){
System.out.println(BLENDED); // <--- Products.BLENDED
System.out.println(BOOK); // <--- Products.BOOK
System.out.println(DVD); // <--- Products.DVD
doits(); // <--- Metadata.doits();
}
}
参考
- Java World (ジャバ・ワールド) 2007年 2月号 val.116 最終号 [雑誌] 総復習! 現代Java開発の必修技術 Part1 J2SE 5.0 の新言語機能 (108~109ページ)
- Joshua Bloch 著 / Effective Java プログラミング言語ガイド
ついに JavaWorld も休刊。デザインがカッコよかったのになぁ……
tags: zlashdot Java Java
Posted by NI-Lab. (@nilab)