Metadataのサンプル

以前に一度、Java5の仕様評価をしたとき、先のログ(「Metadataとは」)で書いた「Dynamicな利用」は、煩雑さが先に立ってしまっている印象を受けた。

Javaでは、「なんで、こんな仕様が??」ということがしばしばあって、Log4Jというデファクトスタンダードに対抗するように、1.4でloggingの機構が用意されたのは有名。
アノテーションについては、XDocletになんで対抗するんだろ、との印象がぬぐえなかった。

以下、Java5で標準として用意されたAnnotationについてサンプリングする。
Java5では、以下の6種類のAnnotationが標準で用意された(自作することも可能)。

Annotation 意味
Deprecated (将来的になくなるため)非推奨とする、ということを意味する
Override スーパークラスのメソッドをオーバーライドしている、と宣言する
Inherited サブクラスにもアノテーションを引き継ぐ
Retension アノテーションの利用方法(SOURCE、RUNTIME)を規定する
Target アノテーションの対象(クラス、メソッドなど)を規定する
Documented Javadocアノテーションを表記するようにする


このうち、プログラムコードそのものに関係するのは、DeprecatedとOverrideの2種類。

以下に、この2種類に関するサンプルプログラムを示す。

Deprecatedのサンプル

Deprecatedは、「このメソッドは、もう(他人に)使わせたくない」という場合に有用。

package test;

/**
 * Metadataのサンプル1
 * (Deprecated)
 */
public class ExampleMetadata1 {
    
    public String overrided(int i, String _str){
        return _str;
    }

    // (A) 非推奨メソッドの定義
    @Deprecated
    public void deplicatedMethod(){
        System.out.println("This method is deprecated!!");
        }

}

この例では、(A)でdeplicatedMethod()メソッドを非推奨としている。
Java5のアノテーションは、(Javadocコメントの中ではなく)コードの中にそのまま@付きで書き込む。

Eclipseでこのコードを書くと、メソッド名に取り消し線が表示される。

Overrideのサンプル

上で用いたサンプルを使って以下のプログラムを作成する。
Overrideは、「オーバーライド(上書き)をしたつもりが、やりそこねている」というミスを防止するために有用。

package test;

/**
 * Metadataのサンプル2
 * (Override)
 */
public class ExampleMetadata2 extends ExampleMetadata1{
    
    public static void main(String[] args) {
        ExampleMetadata1 _em = new ExampleMetadata1();
        _em.deplicatedMethod(); // (a) 非推奨メソッドの利用
    }

    // (b) 正しくOverrideしている。
    @Override
    public String overrided(int i, String _str){
        return _str;
    }

    // (c) Overrideしているつもりが、Overloadしている。
    @Override
    public String overrided(String _str){
        return _str;
    }
}

(A)では、スーパークラスExampleMetadata1で、@Deprecatedとなっているメソッドを利用している。
Eclipseでは、(デフォルトの設定でコンパイル時の)警告となり、deplicatedMethodに取り消し線が入る(下図)。

(C)が、@Overrideで検出したいミス。
これはコンパイルエラーとなる。