Java注释@interface的用法

   java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。
@Override,@Deprecated,@SuppressWarnings为常见的3个注解。
注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记,以后,
JAVAC编译器,开发工具和其他程序可以用反射来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事。

      注解@Override用在方法上,当我们想重写一个方法时,在方法上加@Override,当我们方法
的名字出错时,编译器就会报错,如图:


       注解@Deprecated,用来表示某个类的属性或方法已经过时,不想别人再用时,在属性和方法
上用@Deprecated修饰,如图:

 

  注解@SuppressWarnings用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候,
 如图:

 

注解@Retention可以用来修饰注解,是注解的注解,称为元注解。
Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型,
这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。RetentionPolicy有3个值:CLASS  RUNTIME   SOURCE
用@Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候;
用@Retention(RetentionPolicy.SOURCE )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中;
用@Retention(RetentionPolicy.RUNTIME )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时,
所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用.

 

  1         package com.self;  
  2         import java.lang.annotation.Retention;  
  3         import java.lang.annotation.RetentionPolicy;  
  4           
  5         @Retention(RetentionPolicy.RUNTIME)  
  6         public @interface MyTarget  
  7         { }  
  8         定义个一注解@MyTarget,用RetentionPolicy.RUNTIME修饰;  
  9         package com.self;  
 10         import java.lang.reflect.Method;  
 11         public class MyTargetTest  
 12         {  
 13          @MyTarget  
 14          public void doSomething()  
 15          {  
 16           System.out.println("hello world");  
 17          }  
 18            
 19          public static void main(String[] args) throws Exception  
 20          {  
 21           Method method = MyTargetTest.class.getMethod("doSomething",null);  
 22           if(method.isAnnotationPresent(MyTarget.class))//如果doSomething方法上存在注解@MyTarget,则为true  
 23           {  
 24            System.out.println(method.getAnnotation(MyTarget.class));  
 25           }  
 26           }  
 27         }  
 28         上面程序打印:@com.self.MyTarget(),如果RetentionPolicy值不为RUNTIME,则不打印。  
 29           
 30          @Retention(RetentionPolicy.SOURCE )  
 31         public @interface Override  
 32           
 33         @Retention(RetentionPolicy.SOURCE )  
 34         public @interface SuppressWarnings  
 35           
 36         @Retention(RetentionPolicy.RUNTIME )  
 37         public @interface Deprecated  
 38         由上可以看出,只有注解@Deprecated在运行时可以被JVM读取到  
 39           
 40         注解中可以定义属性,看例子:  
 41         @Retention(RetentionPolicy.RUNTIME)  
 42         public @interface MyAnnotation  
 43         {  
 44          String hello() default "gege";  
 45           String world();  
 46           int[] array() default { 2, 4, 5, 6 };  
 47           EnumTest.TrafficLamp lamp() ;  
 48           TestAnnotation lannotation() default @TestAnnotation(value = "ddd");  
 49           Class style() default String.class;  
 50         }  
 51         上面程序中,定义一个注解@MyAnnotation,定义了6个属性,他们的名字为:  
 52         hello,world,array,lamp,lannotation,style.  
 53         属性hello类型为String,默认值为gege  
 54         属性world类型为String,没有默认值  
 55         属性array类型为数组,默认值为2,4,5,6  
 56         属性lamp类型为一个枚举,没有默认值  
 57         属性lannotation类型为注解,默认值为@TestAnnotation,注解里的属性是注解  
 58         属性style类型为Class,默认值为String类型的Class类型  
 59           
 60         看下面例子:定义了一个MyTest类,用注解@MyAnnotation修饰,注解@MyAnnotation定义的属性都赋了值  
 61         @MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)  
 62         public class MyTest  
 63         {  
 64          @MyAnnotation(lannotation=@TestAnnotation(value="baby"), world = "shanghai",array={1,2,3},lamp=TrafficLamp.YELLOW)  
 65          @Deprecated  
 66          @SuppressWarnings("")  
 67          public void output()  
 68          {  
 69           System.out.println("output something!");  
 70          }  
 71         }  
 72          接着通过反射读取注解的信息:  
 73         public class MyReflection  
 74         {  
 75          public static void main(String[] args) throws Exception  
 76          {  
 77           MyTest myTest = new MyTest();  
 78             Class<MyTest> c = MyTest.class;  
 79             Method method = c.getMethod("output", new Class[] {});  
 80                //如果MyTest类名上有注解@MyAnnotation修饰,则为true  
 81           if(MyTest.class.isAnnotationPresent(MyAnnotation.class))  
 82           {  
 83            System.out.println("have annotation");  
 84           }  
 85            if (method.isAnnotationPresent(MyAnnotation.class))  
 86            {  
 87            method.invoke(myTest, null); //调用output方法  
 88            //获取方法上注解@MyAnnotation的信息  
 89              MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);  
 90             String hello = myAnnotation.hello();  
 91            String world = myAnnotation.world();  
 92            System.out.println(hello + ", " + world);//打印属性hello和world的值  
 93            System.out.println(myAnnotation.array().length);//打印属性array数组的长度  
 94            System.out.println(myAnnotation.lannotation().value()); //打印属性lannotation的值  
 95            System.out.println(myAnnotation.style());  
 96            }  
 97             //得到output方法上的所有注解,当然是被RetentionPolicy.RUNTIME修饰的  
 98              Annotation[] annotations = method.getAnnotations();  
 99               for (Annotation annotation : annotations)  
100           {  
101            System.out.println(annotation.annotationType().getName());  
102           }  
103            }  
104         }  
105         上面程序打印:  
106         have annotation  
107         output something!  
108         gege, shanghai  
109         3  
110         baby  
111         class java.lang.String  
112         com.heima.annotation.MyAnnotation  
113         java.lang.Deprecated  
114           
115         如果注解中有一个属性名字叫value,则在应用时可以省略属性名字不写。  
116         可见,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解属性值,属性名字是value,  
117         属性的返回类型是RetentionPolicy,如下:  
118         public @interface MyTarget  
119         {  
120             String value();  
121         }  
122         可以这样用:  
123           @MyTarget("aaa")  
124          public void doSomething()  
125          {  
126           System.out.println("hello world");  
127          }  
128            
129         注解@Target也是用来修饰注解的元注解,它有一个属性ElementType也是枚举类型,  
130         值为:ANNOTATION_TYPE CONSTRUCTOR  FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE  
131         如@Target(ElementType.METHOD) 修饰的注解表示该注解只能用来修饰在方法上。  
132         @Target(ElementType.METHOD)  
133         @Retention(RetentionPolicy.RUNTIME)  
134         public @interface MyTarget  
135         {  
136          String value() default "hahaha";  
137         }  
138         如把@MyTarget修饰在类上,则程序报错,如:  
139         @MyTarget  
140         public class MyTargetTest  
141         注解大都用在开发框架中吧,好了有关注解就学习那么多了,谢谢。 

 

posted @ 2015-07-23 14:38  别人眼中的过客  阅读(359)  评论(0编辑  收藏  举报