父类上的注解可以被子类继承吗?

-----------------------------------------------------------------

我们知道在编写自定义注解时,可以通过指定@Inherited注解,指明自定义注解是否可以被继承。但实现情况又可细分为多种。

测试环境如下:

-----------------------------------------------------------------

父类的类上和方法上有自定义的注解--MyAnnotation

子类继承了这个父类,分别:

子类方法,实现了父类上的抽象方法

子类方法,继承了父类上的方法

子类方法,覆盖了父类上的方法

MyAnnotation自定义注解

-----------------------------------------------------------------

Java代码  

packagetest.annotation;importjava.lang.annotation.Inherited;importjava.lang.annotation.Retention;/*** 自定义注解*/
//@Inherited//可以被继承
@Retention (java.lang.annotation.RetentionPolicy.RUNTIME) //可以通过反射读取注解
public @interfaceMyAnnotation {
String value();
}

父类

-----------------------------------------------------------------

Java代码  

packagetest.annotation;
@MyAnnotation (value= "类名上的注解")public abstract classParentClass {
@MyAnnotation (value= "父类的abstractMethod方法")public abstract voidabstractMethod();
@MyAnnotation (value= "父类的doExtends方法")public voiddoExtends() {
System.out.println(" ParentClass doExtends ...");
}
@MyAnnotation (value= "父类的doHandle方法")public voiddoHandle(){
System.out.println(" ParentClass doHandle ...");
}
}

子类

-----------------------------------------------------------------

Java代码  

packagetest.annotation;public class SubClass extendsParentClass{//子类实现父类的抽象方法
@Overridepublic voidabstractMethod() {
System.out.println("子类实现父类的abstractMethod抽象方法");
}//子类继承父类的doExtends方法//子类覆盖父类的doHandle方法
@Overridepublic voiddoHandle(){
System.out.println("子类覆盖父类的doHandle方法");
}
}

测试类

-----------------------------------------------------------------

Java代码  

packagetest.annotation;importjava.lang.reflect.Method;public classMainTest {public static void main(String[] args) throwsSecurityException,
NoSuchMethodException {
Class clazz = SubClass.class;if (clazz.isAnnotationPresent(MyAnnotation. class)) {
MyAnnotation cla=clazz
.getAnnotation(MyAnnotation.class);
System.out.println("子类继承到父类类上Annotation,其信息如下:" +cla.value());
}else{
System.out.println("子类没有继承到父类类上Annotation");
}//实现抽象方法测试
Method method = clazz.getMethod("abstractMethod" , newClass[] {});if (method.isAnnotationPresent(MyAnnotation. class)) {
MyAnnotation ma=method
.getAnnotation(MyAnnotation.class);
System.out.println("子类实现父类的abstractMethod抽象方法,继承到父类抽象方法中的Annotation,其信息如下:" +ma.value());
}else{
System.out.println("子类实现父类的abstractMethod抽象方法,没有继承到父类抽象方法中的Annotation");
}//覆盖测试
Method methodOverride = clazz.getMethod("doExtends" , newClass[] {});if (methodOverride.isAnnotationPresent(MyAnnotation. class)) {
MyAnnotation ma=methodOverride
.getAnnotation(MyAnnotation.class);
System.out
.println("子类继承父类的doExtends方法,继承到父类doExtends方法中的Annotation,其信息如下:" +ma.value());
}else{
System.out.println("子类继承父类的doExtends方法,没有继承到父类doExtends方法中的Annotation");
}//继承测试
Method method3 = clazz.getMethod("doHandle" , newClass[] {});if (method3.isAnnotationPresent(MyAnnotation. class)) {
MyAnnotation ma=method3
.getAnnotation(MyAnnotation.class);
System.out
.println("子类覆盖父类的doHandle方法,继承到父类doHandle方法中的Annotation,其信息如下:" +ma.value());
}else{
System.out.println("子类覆盖父类的doHandle方法,没有继承到父类doHandle方法中的Annotation");
}
}
}

编写自定义注解时未写@Inherited的运行结果

-----------------------------------------------------------------

子类没有继承到父类类上Annotation

子类实现父类的abstractMethod抽象方法,没有继承到父类抽象方法中的Annotation

子类继承父类的doExtends方法,继承到父类doExtends方法中的Annotation,其信息如下:父类的doExtends方法

子类覆盖父类的doHandle方法,没有继承到父类doHandle方法中的Annotation

编写自定义注解时写了@Inherited的运行结果

-----------------------------------------------------------------

子类继承到父类类上Annotation,其信息如下:类名上的注解

子类实现父类的abstractMethod抽象方法,没有继承到父类抽象方法中的Annotation

子类继承父类的doExtends方法,继承到父类doExtends方法中的Annotation,其信息如下:父类的doExtends方法

子类覆盖父类的doHandle方法,没有继承到父类doHandle方法中的Annotation

结论

-----------------------------------------------------------------

父类的类上和方法上有自定义的注解,

子类继承了这个父类,的情况下。

编写自定义注解时未写@Inherited的运行结果:

编写自定义注解时写了@Inherited的运行结果:

子类的类上能否继承到父类的类上的注解?

子类方法,实现了父类上的抽象方法,这个方法能否继承到注解?

子类方法,继承了父类上的方法,这个方法能否继承到注解?

子类方法,覆盖了父类上的方法,这个方法能否继承到注解?

我们知道在编写自定义注解时,可以通过指定@Inherited注解,指明自定义注解是否可以被继承。

通过测试结果来看,@Inherited 只是可控制 对类名上注解是否可以被继承。不能控制方法上的注解是否可以被继承。

附注

-----------------------------------------------------------------

Spring 实现事务的注解@Transactional 是可以被继承的,

通过查看它的源码可以看到@Inherited。