Java注释@interface的用法【转】 àì夳堔傛蜴生んèń 2022-06-12 12:49 143阅读 0赞 ## 1.概述 ## <1> java用 **@interface Annotation\{ \} **定义一个注解 @Annotation,一个注解是一个类。 ** <2> @Override,@Deprecated,@SuppressWarnings**为常见的3个注解。 <3> 注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记,以后,JAVAC编译器,开发工具和其他程序可以用**反射**来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事。 <4> 注解@Override用在方法上,当我们想重写一个方法时,在方法上加@Override,当我们方法的名字出错时,编译器就会报错,如图: ![0_1320340910A8xa.gif][] 注解@Deprecated,用来表示某个类的属性或方法已经过时,不想别人再用时,在属性和方法上用@Deprecated修饰,如图: ![0_1320340969Vgmw.gif][] 注解@SuppressWarnings用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候,如图: ![0_1320341021mJWH.gif][] ## 2.自定义注解 ## 注解@Retention可以用来修饰注解,是注解的注解,称为元注解。Retention注解有一个属性value,是RetentionPolicy类型的,RetentionPolicy是一个枚举类型,在自定义注解中,我们需要用到元注解(@Retention)来定义我们自定义的注解的“保持”方式。 【重点】这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。RetentionPolicy有3个值: ** CLASS RUNTIME SOURCE** <1> 用@Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译,但,在运行的时候不会被虚拟机读取,这种方式用得比较少; <2> 用@Retention(RetentionPolicy.SOURCE )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在**源文件**中,例如@Override,@Deprecated就属于这一类应用; <3>用@Retention(RetentionPolicy.RUNTIME )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时, 所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用. (1)自定义一个注解: /** * 自定义个一注解:@MyTarget,用RetentionPolicy.RUNTIME修饰; */ @Retention(RetentionPolicy.RUNTIME) public @interface MyTarget { } (2) 自定义注解的简单实例 public class MyTargetTest { @MyTarget public void doSomething() { System.out.println("hello world"); } public static void main(String[] args) throws Exception { Method method = MyTargetTest.class.getMethod("doSomething",null); if(method.isAnnotationPresent(MyTarget.class))//如果doSomething方法上存在注解@MyTarget,则为true { System.out.println(method.getAnnotation(MyTarget.class)); } } } 输出结果: @com .self.MyTarget(),如果RetentionPolicy值不为RUNTIME,则不打印。 **\[java\]** [view plain][] [copy][view plain] 1. 2. @Retention(RetentionPolicy.SOURCE ) 3. **public** **@interface** Override 4. 5. @Retention(RetentionPolicy.SOURCE ) 6. **public** **@interface** SuppressWarnings 7. 8. @Retention(RetentionPolicy.RUNTIME ) 9. **public** **@interface** Deprecated 10. 由上可以看出,只有注解@Deprecated在运行时可以被JVM读取到 11. 12. 注解中可以定义属性,看例子: 13. @Retention(RetentionPolicy.RUNTIME) 14. **public** **@interface** MyAnnotation 15. \{ 16. String hello() **default** "gege"; 17. String world(); 18. **int**\[\] array() **default** \{ 2, 4, 5, 6 \}; 19. EnumTest.TrafficLamp lamp() ; 20. TestAnnotation lannotation() **default** @TestAnnotation(value = "ddd"); 21. Class style() **default** String.**class**; 22. \} 23. 上面程序中,定义一个注解@MyAnnotation,定义了6个属性,他们的名字为: 24. hello,world,array,lamp,lannotation,style. 25. 属性hello类型为String,默认值为gege 26. 属性world类型为String,没有默认值 27. 属性array类型为数组,默认值为2,4,5,6 28. 属性lamp类型为一个枚举,没有默认值 29. 属性lannotation类型为注解,默认值为@TestAnnotation,注解里的属性是注解 30. 属性style类型为Class,默认值为String类型的Class类型 31. 32. 看下面例子:定义了一个MyTest类,用注解@MyAnnotation修饰,注解@MyAnnotation定义的属性都赋了值 33. @MyAnnotation(hello = "beijing", world="shanghai",array=\{\},lamp=TrafficLamp.RED,style=**int**.**class**) 34. **public** **class** MyTest 35. \{ 36. @MyAnnotation(lannotation=@TestAnnotation(value="baby"), world = "shanghai",array=\{ 1,2,3\},lamp=TrafficLamp.YELLOW) 37. @Deprecated 38. @SuppressWarnings("") 39. **public** **void** output() 40. \{ 41. System.out.println("output something!"); 42. \} 43. \} 44. 接着通过反射读取注解的信息: 45. **public** **class** MyReflection 46. \{ 47. **public** **static** **void** main(String\[\] args) **throws** Exception 48. \{ 49. MyTest myTest = **new** MyTest(); 50. Class<MyTest> c = MyTest.**class**; 51. Method method = c.getMethod("output", **new** Class\[\] \{\}); 52. //如果MyTest类名上有注解@MyAnnotation修饰,则为true 53. **if**(MyTest.**class**.isAnnotationPresent(MyAnnotation.**class**)) 54. \{ 55. System.out.println("have annotation"); 56. \} 57. **if** (method.isAnnotationPresent(MyAnnotation.**class**)) 58. \{ 59. method.invoke(myTest, **null**); //调用output方法 60. //获取方法上注解@MyAnnotation的信息 61. MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.**class**); 62. String hello = myAnnotation.hello(); 63. String world = myAnnotation.world(); 64. System.out.println(hello + ", " + world);//打印属性hello和world的值 65. System.out.println(myAnnotation.array().length);//打印属性array数组的长度 66. System.out.println(myAnnotation.lannotation().value()); //打印属性lannotation的值 67. System.out.println(myAnnotation.style()); 68. \} 69. //得到output方法上的所有注解,当然是被RetentionPolicy.RUNTIME修饰的 70. Annotation\[\] annotations = method.getAnnotations(); 71. **for** (Annotation annotation : annotations) 72. \{ 73. System.out.println(annotation.annotationType().getName()); 74. \} 75. \} 76. \} 77. 上面程序打印: 78. have annotation 79. output something! 80. gege, shanghai 81. 3 82. baby 83. **class** java.lang.String 84. com.heima.annotation.MyAnnotation 85. java.lang.Deprecated 86. 87. 如果注解中有一个属性名字叫value,则在应用时可以省略属性名字不写。 88. 可见,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解属性值,属性名字是value, 89. 属性的返回类型是RetentionPolicy,如下: 90. **public** **@interface** MyTarget 91. \{ 92. String value(); 93. \} 94. 可以这样用: 95. @MyTarget("aaa") 96. **public** **void** doSomething() 97. \{ 98. System.out.println("hello world"); 99. \} 100. 101. 注解@Target也是用来修饰注解的元注解,它有一个属性ElementType也是枚举类型, 102. 值为:ANNOTATION\_TYPE CONSTRUCTOR FIELD LOCAL\_VARIABLE METHOD PACKAGE PARAMETER TYPE 103. 如@Target(ElementType.METHOD) 修饰的注解表示该注解只能用来修饰在方法上。 104. @Target(ElementType.METHOD) 105. @Retention(RetentionPolicy.RUNTIME) 106. **public** **@interface** MyTarget 107. \{ 108. String value() **default** "hahaha"; 109. \} 110. 如把@MyTarget修饰在类上,则程序报错,如: 111. @MyTarget 112. **public** **class** MyTargetTest 113. 注解大都用在开发框架中吧,好了有关注解就学习那么多了,谢谢。 [0_1320340910A8xa.gif]: /images/20220612/189004d1620142698df7318f6ca0a147.png [0_1320340969Vgmw.gif]: /images/20220612/25fcae0a1257460c95fb18b06b53d618.png [0_1320341021mJWH.gif]: /images/20220612/d2628dab1f494d2c8b40305c5fe28d41.png [view plain]: http://blog.csdn.net/liuwenbo0920/article/details/7290586#
还没有评论,来说两句吧...