java.lang.annotation.Inheritedメタ・アノテーション

あるアノテーションAにより修飾されているクラスBがあったとき、このクラスBを継承するクラスをクラスCとする。
このとき、アノテーションAが、Inheritedアノテーションにより修飾されていると、クラスBだけでなく、そのサブクラスであるクラスCもアノテーションAにより修飾されていることになる。
つまり、アノテーションAもクラスCに継承されることになる。


以下例を示す。
まず、Carアノテーションを用意する。

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Car {
}

次に、Carアノテーションを持つ、SportsCarクラスを用意する。

@Car
public class SportsCar {
}

そして、このSportsCarクラスを継承するPorscheクラスを用意する。

public class Porsche extends SportsCar {
}

以下の処理で、PorscheクラスにCarアノテーションが継承されていることを確認する。

import java.lang.annotation.Annotation;
import static java.lang.System.out;

public class Main {
    public static void main(String args[]) {
        out.println("SportsCar -------------------------");
        for (Annotation a : SportsCar.class.getAnnotations()) {
            out.println(a);
        }
        out.println(SportsCar.class.isAnnotationPresent(Car.class));

        out.println("Porsche ---------------------------");
        for (Annotation a : Porsche.class.getAnnotations()) {
            out.println(a);
        }
        out.println(Porsche.class.isAnnotationPresent(Car.class));
    }
}

上記処理を実行すると以下の結果が得られる。

SportsCar -------------------------
@Car()
true
Porsche ---------------------------
@Car()
true

この結果より、PorscheクラスのソースにはCarアノテーションが定義されていないのに、PorscheクラスからCarアノテーションが取得されていることがわかる。


また、Carアノテーションから、@Inheritedをコメントアウトすると、以下の結果が得られる。

SportsCar -------------------------
@Car()
true
Porsche ---------------------------
false

これは、Porscheクラスに、SportsCarクラスのアノテーションが継承されていないことを示している。