Annotation定义

Annotation接口的实现类: Documented, Inherited, Retention, Target 都是用来定义自己定义的Annotation类的。

1. 注解(Annotation)类,以@interface  修饰 ,不能显示(explicit)extends或implements任何类

如:

java 代码
  1. public @interface DefineAnnotation {   
  2. }  

 

这种没有任何属性的Annotation类,也叫标识Annotation

2. 定义属性

java 代码
  1. //属性必须加个小括号   
  2. public String value() ;   
  3. //有默认值的属性   
  4. public String value() default "aaa";  

 

完整定义如下:

java 代码
  1. //注解Annotation类不能显示(explicit)extends或implements任何类   
  2. //不定义任何属性就叫maket annotation   
  3. public @interface DefineAnnotation {   
  4.   
  5.     //定义一个属性,有属性的话,必须赋值,除非有默认default   
  6.     public String value() default "aaa";   
  7.        
  8. }   

 

3.使用Annotation,有默认值的可以不用传参数,也可以传递参数。没有默认值的,必须传递参数。

如:

java 代码
  1. public class TestAnnotation {   
  2.   
  3. //  @DefineAnnotation 有默认值的第一种使用方式   
  4. //  @DefineAnnotation() 有默认值的第二种使用方式   
  5.     @DefineAnnotation("ttitfly")   
  6.     public void say(){   
  7.         System.out.println("say hello");   
  8.     }   
  9.     public static void main(String[] args){   
  10.         TestAnnotation ta = new TestAnnotation();   
  11.         ta.say();   
  12.     }   
  13. }   

 

4.  Retention (保存)

所有的Annotation类都实现了Annotation接口
@Retention本身就是个Annotation(注解)类
它的值是个enum枚举类型的RetentionPolicy,该枚举类型RetentionPolicy有三个值RUNTIME (会被JVM加载,并可以通过反射来获得到Annotation类的信息) ,CLASS (不会被JVM加载),Source
@Retention的值标识自己定义的Annotation(注解)类 是属于哪种保存策略,将来哪个类如果使用了这个自定义的注解类,将会使用这种保存策略

如:

java 代码
  1. import java.lang.annotation.Retention;   
  2. import java.lang.annotation.RetentionPolicy;   
  3. //所有的Annotation类都实现了Annotation接口   
  4. //@Retention本身就是个Annotation(注解)类   
  5. //它的值是个enum枚举类型的RetentionPolicy,该枚举类型RetentionPolicy有三个值RUNTIME (会被JVM加载,并可以通过反射来获得到Annotation类的信息) ,CLASS (不会被JVM加载),Source   
  6. //@Retention的值标识自己定义的Annotation(注解)类 是属于哪种保存策略,将来哪个类如果使用了这个自定义的注解类,将会使用这种保存策略   
  7. @Retention(RetentionPolicy.RUNTIME)   
  8. public @interface MyAnnotation {   
  9.   
  10.     String hello() default "ttitfly";   
  11.     String world();   
  12. }   

 

java 代码
  1. //使用自己定义的Annotation类   
  2. public class MyTest {   
  3.     //一个方法可以有多个注解类   
  4.     @Deprecated  
  5.     @MyAnnotation(hello="china",world="earth")   
  6.     public void say(){   
  7.         System.out.println("say hello");   
  8.     }   
  9.   
  10. }   

 

 

java 代码
  1. import java.lang.annotation.Annotation;       
  2. import java.lang.reflect.Method;       
  3.       
  4. public class TestMain {       
  5.     //可以通过AnnotatedElement来获得到Annotation类的信息。Method,Field等都是AnnotatedElement的实现类       
  6.     public static void main(String[] args) throws Exception {       
  7.                
  8.         MyTest mt = new MyTest();       
  9.         Class clazz = MyTest.class;       
  10.                
  11.                
  12.         //Method method = clazz.getMethod("say", null);//因为是无参数的,所以直接写个null也可以       
  13.         Method method = clazz.getMethod("say"new Class[]{});       
  14.         method.invoke(mt, new Object[]{});       
  15.                
  16.         //该方法是否使用了MyAnnotation这个注解类       
  17.         boolean isExist = method.isAnnotationPresent(MyAnnotation.class) ;       
  18.         if(isExist){       
  19.             MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);       
  20.             System.out.println(annotation.hello());       
  21.             System.out.println(annotation.world());       
  22.         }       
  23.                
  24.         Annotation[] annotations = method.getAnnotations();       
  25.         for(     Annotation    annotation   :    annotations   ){       
  26.             //打印出这样的结果:com.yahaitt.annotation.MyAnnotation       
  27.             System.out.println(annotation.annotationType().getName());       
  28.                    
  29.             //不能通过getClass().getName()的方式获得了。这样获得的结果类似这样的:$Proxy3,主要原因是因为Annotation在运行时刻,是通过java的动态代理实现的,   
  30.             //每次得到一个annotation,实际上并不是得到该annotation的实例,而是得到了它的一个代理,这个代理java在命名上采用的是$Proxy1,$Proxy2...的形式,数字是按照出现的顺序来定的   
  31.             //而getClass()方法返回的是该对象运行时刻所代表的真实对象,在这里也就是代理对象了   
  32.             System.out.println(annotation.getClass().getName());    
  33.                
  34.             //输出结果为:java.lang.reflect.Proxy   
  35.             System.out.println(annotation.getClass().getSuperclass().getName());     
  36.         }       
  37.                
  38.                
  39.     }       
  40. }     

 

5.继承(Inherited)

在自己定义的Annotation里加入一个@Inherited ,就标识了这个定义的Annotation是可以被继承的

java 代码
  1. import java.lang.annotation.Inherited;   
  2. import java.lang.annotation.Retention;   
  3. import java.lang.annotation.RetentionPolicy;   
  4. //在自己定义的Annotation里加入一个@Inherited ,就标识了这个定义的Annotation是可以被继承的   
  5. @Inherited  
  6. @Retention(RetentionPolicy.RUNTIME)   
  7. public @interface MyInherit {   
  8.     String value();   
  9. }   

 

java 代码
  1. @MyInherit("test class")   
  2. public class Parent {   
  3.     @MyInherit("test method")   
  4.     public void doSomething(){   
  5.         System.out.println("hello");   
  6.     }   
  7. }  

 

java 代码
  1. public class Child extends Parent{   
  2.   
  3. }   

 

java 代码
  1. import java.lang.reflect.Method;   
  2.   
  3.   
  4. public class TestInherit {   
  5.        
  6.     public static void main(String[] args) throws Exception{   
  7. //      Class< Parent > clazz = Parent.class;   
  8.         Class< Child > clazz = Child.class;   
  9.         if(clazz.isAnnotationPresent(MyInherit.class)){   
  10.             MyInherit myInherit = clazz.getAnnotation(MyInherit.class);   
  11.             System.out.println(myInherit.value());   
  12.         }   
  13.            
  14.         Method method = clazz.getMethod("doSomething"new Class[]{});   
  15.         if(method.isAnnotationPresent(MyInherit.class)){   
  16.             MyInherit myInherit = method.getAnnotation(MyInherit.class);   
  17.             System.out.println(myInherit.value());   
  18.         }   
  19.     }   
  20.   
  21. }   

 

输出结果为:

test class
test method

也就是说已经被继承了 。但是在方法上使用的Annotation也被继承了,这点有点不太明白,和文档有点冲突。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值