@Inheritedの動作確認
@Inheritedの動作確認です。JavaDocを確認すると以下のような機能らしい。
- @Inheritedは、アノテーションが自動で継承されることを示すアノテーション。
- アノテーション探索時に、派生クラスにアノテーションが付与されていなければ、自動的に親クラスに付与されたアノテーションが探索される。
- クラスのアノテーションのみで有効。メソッドやフィールドのアノテーションでは無効。
- インターフェイスは探索対象にならない。
ふむふむ。ということで動作確認コードを書く。
/** * テスト用のアノテーション */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) @interface Foo { String value(); } /** * インターフェイス */ @Foo("interface") interface Interface { @Foo("parent-method") public void method(); } /** * 親クラス */ @Foo("parent") class Parent { @Foo("parent-field") protected String field; @Foo("parent-method") public void method() {} } /** * クラス */ class Test extends Parent implements Interface { protected String field; public void method() {} } /** * クラス2 * 親クラスで付与されているInheritedなアノテーションを上書きで定義。 */ @Foo("test2_class") class Test2 extends Parent implements Interface { @Foo("test2-field") protected String field; @Foo("test2-method") public void method() {} } /** * クラス3 * インターフェイスのみ実装。 */ class Test3 implements Interface { protected String field; public void method() {} } .... /** * Fooアノテーションのvalueを取得する。 * @param foo Fooアノテーション * @return Fooアノテーションのvalue/アノテーションがnullであればnull */ static String getValue( Foo foo ) { if ( foo == null ) return "null"; return foo.value(); } ... for ( Class<?> cl : new Class[]{ Test.class, Test2.class, Test3.class } ) { System.out.println("---" + cl.getSimpleName()); System.out.println(getValue(cl.getAnnotation(Foo.class))); System.out.println(getValue(cl.getDeclaredField("field").getAnnotation(Foo.class))); System.out.println(getValue(cl.getDeclaredMethod("method").getAnnotation(Foo.class))); System.out.println(); }
実行結果です。
---Test parent null null ---Test2 test2_class test2-field test2-method ---Test3 null null null
ふむ。書いてある通りですな。