Javaのアノテーションに纏わる小ネタ

Javaアノテーションの定義では各属性のdefault値を設定することができるが、このdefault値の設定を省略した属性は、アノテーションが記述される際に値を設定しないままにするとビルド時にはエラーになる。(チェックされる)

@Documented
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Bind {
    Class FrameType(); //default JFrame.class;
}

このようにBindアノテーションを定義し、実際にコード中に記述する。

@Bind
public class Action {
}

その後ビルドするとエラー発生。

注釈 @Bind は属性 FrameType を定義する必要があります。

これはJavaアノテーションがインタフェース+ダイナミックプロキシで実装されていることと無関係ではないが、この振る舞いを利用して、アノテーションの属性に「必須制約」を持たせることができる訳だ。知っているプログラマには当たり前のことだが、ビルド時にチェックされるJavaアノテーションは地味に便利だったりする。(これと同じこと、C#のカスタム属性ではできなかったよね?)