テスト環境と設定
以下の条件でアノテーションの継承挙動を検証します。
- 親クラスのクラスレベルとメソッドレベルにカスタムアノテーションを定義
- サブクラスが以下の3つのケースをテスト
- 抽象メソッドの実装
- メソッドの継承
- メソッドの上書き
public class AnnotationInheritanceTest {
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
String value();
}
@CustomAnnotation("スーパークラスのアノテーション")
public abstract class BaseClass {
@CustomAnnotation("抽象メソッドのアノテーション")
public abstract void abstractMethod();
@CustomAnnotation("継承メソッドのアノテーション")
public void inheritedMethod() {
System.out.println("BaseClass implementation");
}
@CustomAnnotation("上書きメソッドのアノテーション")
public void overridableMethod() {
System.out.println("BaseClass implementation");
}
}
public class DerivedClass extends BaseClass {
// 抽象メソッドの実装
@Override
public void abstractMethod() {
System.out.println("DerivedClass implementation");
}
// メソッドの上書き
@Override
public void overridableMethod() {
System.out.println("DerivedClass implementation");
}
}
public static void main(String[] args) throws Exception {
Class<DerivedClass> clazz = DerivedClass.class;
// クラスレベルのアノテーションテスト
if (clazz.isAnnotationPresent(CustomAnnotation.class)) {
System.out.println("クラスレベルアノテーション取得成功: " +
clazz.getAnnotation(CustomAnnotation.class).value());
} else {
System.out.println("クラスレベルアノテーション取得失敗");
}
// 抽象メソッドテスト
Method abstractMethod = clazz.getMethod("abstractMethod");
if (abstractMethod.isAnnotationPresent(CustomAnnotation.class)) {
System.out.println("抽象メソッドアノテーション取得成功: " +
abstractMethod.getAnnotation(CustomAnnotation.class).value());
} else {
System.out.println("抽象メソッドアノテーション取得失敗");
}
// 継承メソッドテスト
Method inheritedMethod = clazz.getMethod("inheritedMethod");
if (inheritedMethod.isAnnotationPresent(CustomAnnotation.class)) {
System.out.println("継承メソッドアノテーション取得成功: " +
inheritedMethod.getAnnotation(CustomAnnotation.class).value());
} else {
System.out.println("継承メソッドアノテーション取得失敗");
}
// 上書きメソッドテスト
Method overridenMethod = clazz.getMethod("overridableMethod");
if (overridenMethod.isAnnotationPresent(CustomAnnotation.class)) {
System.out.println("上書きメソッドアノテーション取得成功: " +
overridenMethod.getAnnotation(CustomAnnotation.class).value());
} else {
System.out.println("上書きメソッドアノテーション取得失敗");
}
}
}
テスト結果(@Inherited未使用時)
クラスレベルアノテーション取得失敗
抽象メソッドアノテーション取得失敗
継承メソッドアノテーション取得成功: 継承メソッドのアノテーション
上書きメソッドアノテーション取得失敗
テスト結果(@Inherited使用時)
クラスレベルアノテーション取得成功: スーパークラスのアノテーション
抽象メソッドアノテーション取得失敗
継承メソッドアノテーション取得成功: 継承メソッドのアノテーション
上書きメソッドアノテーション取得失敗
インターフェースの場合
public class InterfaceAnnotationTest {
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
String value();
}
@CustomAnnotation("インターフェースのアノテーション")
public interface BaseInterface {
@CustomAnnotation("インターフェースメソッドのアノテーション")
void interfaceMethod();
}
public class ImplementationClass implements BaseInterface {
@Override
public void interfaceMethod() {
System.out.println("ImplementationClass implementation");
}
}
public static void main(String[] args) throws Exception {
Class<ImplementationClass> clazz = ImplementationClass.class;
// インターフェースレベルアノテーションテスト
for (Class<?> iface : clazz.getInterfaces()) {
if (iface.isAnnotationPresent(CustomAnnotation.class)) {
System.out.println("インターフェースアノテーション取得成功: " +
iface.getAnnotation(CustomAnnotation.class).value());
}
}
// メソッドレベルアノテーションテスト
for (Method method : clazz.getMethods()) {
if (method.isAnnotationPresent(CustomAnnotation.class)) {
System.out.println("メソッドアノテーション取得成功: " +
method.getAnnotation(CustomAnnotation.class).value());
}
}
}
}
インターフェーステスト結果
インターフェースアノテーション取得成功: インターフェースのアノテーション
メソッドアノテーション取得成功: インターフェースメソッドのアノテーション