关闭

Java注释@interface的用法【转】

标签: java
133人阅读 评论(0) 收藏 举报

       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注解的信息,以便在分析程序的时候使用.

[java] view plaincopy
  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 { 2456 };  
  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类型为数组,默认值为2456  
  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. 注解大都用在开发框架中吧,好了有关注解就学习那么多了,谢谢。  
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21404次
    • 积分:300
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:20篇
    • 译文:0篇
    • 评论:1条
    最新评论