子类可以继承到父类上的注解吗--有结论了

来源:互联网 发布:福建文化特色 知乎 编辑:程序博客网 时间:2024/05/16 00:48

博客:http://elf8848.iteye.com

 

不了解注解基础知识的请先看《JDK 5 Annotation\注解\注释\自定义注解》

 

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

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

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

 

 

测试环境如下:

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

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

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

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

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

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

 

 

MyAnnotation自定义注解

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

Java代码  收藏代码
  1. package test.annotation;  
  2. import java.lang.annotation.Inherited;  
  3. import java.lang.annotation.Retention;  
  4. /** 
  5.  * 自定义注解 
  6.  */  
  7. //@Inherited  //可以被继承  
  8. @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)  //可以通过反射读取注解  
  9. public @interface MyAnnotation {    
  10.     String value();    
  11. }   
 

 

父类

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

Java代码  收藏代码
  1. package test.annotation;  
  2. @MyAnnotation(value = "类名上的注解")  
  3. public abstract class ParentClass {  
  4.   
  5.     @MyAnnotation(value = "父类的abstractMethod方法")  
  6.     public abstract void abstractMethod();  
  7.   
  8.     @MyAnnotation(value = "父类的doExtends方法")  
  9.     public void doExtends() {  
  10.         System.out.println(" ParentClass doExtends ...");  
  11.     }  
  12.       
  13.     @MyAnnotation(value = "父类的doHandle方法")  
  14.     public void doHandle(){  
  15.         System.out.println(" ParentClass doHandle ...");  
  16.     }  
  17. }  
 

 

子类

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

Java代码  收藏代码
  1. package test.annotation;  
  2. public class SubClass extends ParentClass{    
  3.     
  4.     //子类实现父类的抽象方法  
  5.     @Override    
  6.     public void abstractMethod() {    
  7.         System.out.println("子类实现父类的abstractMethod抽象方法");    
  8.     }    
  9.       
  10.     //子类继承父类的doExtends方法  
  11.       
  12.     //子类覆盖父类的doHandle方法  
  13.     @Override    
  14.     public void doHandle(){  
  15.         System.out.println("子类覆盖父类的doHandle方法");   
  16.     }  
  17. }   

 

 

测试类

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

Java代码  收藏代码
  1. package test.annotation;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. public class MainTest {  
  6.     public static void main(String[] args) throws SecurityException,  
  7.             NoSuchMethodException {  
  8.   
  9.         Class<SubClass> clazz = SubClass.class;  
  10.   
  11.         if (clazz.isAnnotationPresent(MyAnnotation.class)) {  
  12.             MyAnnotation cla = clazz  
  13.                     .getAnnotation(MyAnnotation.class);  
  14.             System.out.println("子类继承到父类类上Annotation,其信息如下:"+cla.value());  
  15.         } else {  
  16.             System.out.println("子类没有继承到父类类上Annotation");  
  17.         }  
  18.   
  19.         // 实现抽象方法测试  
  20.         Method method = clazz.getMethod("abstractMethod"new Class[] {});  
  21.         if (method.isAnnotationPresent(MyAnnotation.class)) {  
  22.             MyAnnotation ma = method  
  23.                     .getAnnotation(MyAnnotation.class);  
  24.             System.out.println("子类实现父类的abstractMethod抽象方法,继承到父类抽象方法中的Annotation,其信息如下:"+ma.value());  
  25.         } else {  
  26.             System.out.println("子类实现父类的abstractMethod抽象方法,没有继承到父类抽象方法中的Annotation");  
  27.         }  
  28.   
  29.         //覆盖测试  
  30.         Method methodOverride = clazz.getMethod("doExtends"new Class[] {});  
  31.         if (methodOverride.isAnnotationPresent(MyAnnotation.class)) {  
  32.             MyAnnotation ma = methodOverride  
  33.                     .getAnnotation(MyAnnotation.class);  
  34.             System.out  
  35.                     .println("子类继承父类的doExtends方法,继承到父类doExtends方法中的Annotation,其信息如下:"+ma.value());  
  36.         } else {  
  37.             System.out.println("子类继承父类的doExtends方法,没有继承到父类doExtends方法中的Annotation");  
  38.         }  
  39.   
  40.         //继承测试  
  41.         Method method3 = clazz.getMethod("doHandle"new Class[] {});  
  42.         if (method3.isAnnotationPresent(MyAnnotation.class)) {  
  43.             MyAnnotation ma = method3  
  44.                     .getAnnotation(MyAnnotation.class);  
  45.             System.out  
  46.                     .println("子类覆盖父类的doHandle方法,继承到父类doHandle方法中的Annotation,其信息如下:"+ma.value());  
  47.         } else {  
  48.             System.out.println("子类覆盖父类的doHandle方法,没有继承到父类doHandle方法中的Annotation");  
  49.         }  
  50.     }  
  51. }  
  

 

编写自定义注解时未写@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。



另一篇 :

1、声明

以下是java.lang.Package.isAnnotationPresent()方法的声明

1
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)

2、参数

annotationClass -- 对应于注释类型的Class对象

3、返回值

如果一个注解指定注释类型是存在于此元素上此方法返回true,否则返回false

4、异常

NullPointerException -- 如果给定的注释类为null

5、例子

下面的例子显示lang.Object.isAnnotationPresent()方法的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.yiibai;
 
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
 
// declare a new annotation
@Retention(RetentionPolicy.RUNTIME)
@interface Demo {
    
   String str();
    
   int val();
}
 
public class PackageDemo {
 
   // set values for the annotation
   @Demo(str = "Demo Annotation", val = 100)
   // a method to call in the main
   public static void example() {
      PackageDemo ob = new PackageDemo();
       
      try {
         Class c = ob.getClass();
 
         // get the method example
         Method m = c.getMethod("example");
 
         // get the annotation for class Demo
         Demo annotation = m.getAnnotation(Demo.class);
 
         // print the annotation
         System.out.println(annotation.str() + " " + annotation.val());
      catch (NoSuchMethodException exc) {
         exc.printStackTrace();
      }
   }
    
   public static void main(String args[]) {
      example();
       
      Package[] pack = Package.getPackages();
      // check if annotation hello exists
      for (int i = 0; i < pack.length; i++) {
         System.out.println("" + pack[i].isAnnotationPresent(Demo.class));
      }
   }
}

编译和运行上面的程序,这将产生以下结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Demo Annotation 100
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false

0 0