Java注释@interface
来源:互联网 发布:mac 系统没装上 按d 编辑:程序博客网 时间:2024/05/19 17:09
java用 @interfaceAnnotation{ } 定义一个注解@Annotation,一个注解是一个类。
@Override,@Deprecated,@SuppressWarnings为常见的3个注解。
注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记,以后,
JAVAC编译器,开发工具和其他程序可以用反射来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事。
注解@Override用在方法上,当我们想重写一个方法时,在方法上加@Override,当我们方法
的名字出错时,编译器就会报错,如图:
注解@Deprecated,用来表示某个类的属性或方法已经过时,不想别人再用时,在属性和方法
上用@Deprecated修饰,如图:
注解@SuppressWarnings用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候,
如图:
@Retention
可以用来修饰注解,是注解的注解,称为元注解。
Retention注解有一个属性value,是RetentionPolicy类型的,EnumRetentionPolicy是一个枚举类型,这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention搭配RententionPolicy使用。RetentionPolicy有3个值:CLASS RUNTIME SOURCE
用@Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候;
用@Retention(RetentionPolicy.SOURCE)修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中;
用@Retention(RetentionPolicy.RUNTIME)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时,
@Target:
指定程序元定义的注释所使用的地方,它使用了另一个类:ElementType,是一个枚举类定义了注释类型可以应用到不同的程序元素以免使用者误用。看看java.lang.annotation 下的源代码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
ElementType是一个枚举类型,指明注释可以使用的地方,看看ElementType类:
public enum ElementType {
TYPE, // 指定适用点为 class, interface, enum
FIELD, // 指定适用点为 field
METHOD, // 指定适用点为 method
PARAMETER, // 指定适用点为 method 的 parameter
CONSTRUCTOR, // 指定适用点为 constructor
LOCAL_VARIABLE, // 指定使用点为 局部变量
ANNOTATION_TYPE, //指定适用点为 annotation 类型
PACKAGE // 指定适用点为 package
}
@Documented:是一个标记注释,表示注释应该出现在类的javadoc中,因为在默认情况下注释时不包括在javadoc中的。
所以如果花费了大量的时间定义一个注释类型,并想描述注释类型的作用,可以使用它。
注意他与@Retention(RetentionPolicy.RUNTIME)配合使用,因为只有将注释保留在编译后的类文件中由虚拟机加载,
然后javadoc才能将其抽取出来添加至javadoc中。
@Inherited:将注释同样继承至使用了该注释类型的方法中(表达有点问题,就是如果一个方法使用了的注释用了@inherited,
那么其子类的该方法同样继承了该注释)
注意事项:
1.所有的Annotation自动继承java.lang.annotation接口
2.自定义注释的成员变量访问类型只能是public、default;(所有的都能访问,源作者没用到函数:getDeclaredFields而已)
3.成员变量的只能使用基本类型(byte、short、int、char、long、double、float、boolean和String、Enum、Class、annotations以及该类型的数据)(没有限制,大家可以修改测试一下,就清楚)
4.如果只有一个成员变量,最好将参数名称设为value,赋值时不用制定名称而直接赋值
5.在实际应用中,还可以使用注释读取和设置Bean中的变量。
可以用反射的方式读取。RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用.
[java] view plain copy
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. @Retention(RetentionPolicy.RUNTIME)
41. public @interface MyAnnotation
42. {
43. String hello() default "gege";
44. String world();
45. int[] array() default { 2, 4, 5, 6 };
46. EnumTest.TrafficLamp lamp() ;
47. TestAnnotation lannotation() default @TestAnnotation(value = "ddd");
48. Class style() default String.class;
49. }
50. 上面程序中,定义一个注解@MyAnnotation,定义了6个属性,他们的名字为:
51. hello,world,array,lamp,lannotation,style.
52. 属性hello类型为String,默认值为gege
53. 属性world类型为String,没有默认值
54. 属性array类型为数组,默认值为2,4,5,6
55. 属性lamp类型为一个枚举,没有默认值
56. 属性lannotation类型为注解,默认值为@TestAnnotation,注解里的属性是注解
57. 属性style类型为Class,默认值为String类型的Class类型
58.
59. 看下面例子:定义了一个MyTest类,用注解@MyAnnotation修饰,注解@MyAnnotation定义的属性都赋了值
----------------------------------
60. @MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)
61. public class MyTest
62. {
63. @MyAnnotation(lannotation=@TestAnnotation(value="baby"), world = "shanghai",array={1,2,3},lamp=TrafficLamp.YELLOW)
64. @Deprecated
65. @SuppressWarnings("")
66. public void output()
67. {
68. System.out.println("output something!");
69. }
70. }
71.----------------------------------
72.
73. 接着通过反射读取注解的信息:
74. public class MyReflection
75. {
76. public static void main(String[] args) throws Exception
77. {
78. MyTest myTest = new MyTest();
79. Class<MyTest> c = MyTest.class;
80. Method method = c.getMethod("output", new Class[] {});
81. //如果MyTest类名上有注解@MyAnnotation修饰,则为true
82. if(MyTest.class.isAnnotationPresent(MyAnnotation.class))
83. {
84. System.out.println("have annotation");
85. }
86. if (method.isAnnotationPresent(MyAnnotation.class))
87. {
88. method.invoke(myTest, null); //调用output方法
89. //获取方法上注解@MyAnnotation的信息
90. MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
91. String hello = myAnnotation.hello();
92. String world = myAnnotation.world();
93. System.out.println(hello + ", " + world);//打印属性hello和world的值
94. System.out.println(myAnnotation.array().length);//打印属性array数组的长度
95. System.out.println(myAnnotation.lannotation().value()); //打印属性lannotation的值
96. System.out.println(myAnnotation.style());
97. }
98. //得到output方法上的所有注解,当然是被RetentionPolicy.RUNTIME修饰的
99. Annotation[] annotations = method.getAnnotations();
100. for (Annotation annotation : annotations)
101. {
102. System.out.println(annotation.annotationType().getName());
103. }
104. }
105. }
106. 上面程序打印:
107. have annotation
108. output something!
109. gege, shanghai
110. 3
111. baby
112. class java.lang.String
113. com.heima.annotation.MyAnnotation
114. java.lang.Deprecated
115.
116. 如果注解中有一个属性名字叫value,则在应用时可以省略属性名字不写。
117. 可见,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解属性值,属性名字是value,
118. 属性的返回类型是RetentionPolicy,如下:
119. public @interface MyTarget
120. {
121. String value();
122. }
123. 可以这样用:
124. @MyTarget("aaa")
125. public void doSomething()
126. {
127. System.out.println("hello world");
128. }
129.
130. 注解@Target也是用来修饰注解的元注解,它有一个属性ElementType也是枚举类型,
131. 值为:ANNOTATION_TYPE CONSTRUCTOR FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE
132. 如@Target(ElementType.METHOD) 修饰的注解表示该注解只能用来修饰在方法上。
133. @Target(ElementType.METHOD)
134. @Retention(RetentionPolicy.RUNTIME)
135. public @interface MyTarget
136. {
137. String value() default "hahaha";
138. }
139. 如把@MyTarget修饰在类上,则程序报错,如:
140. @MyTarget
141. public class MyTargetTest
142. 注解大都用在开发框架中吧,好了有关注解就学习那么多了,谢谢。
- Java注释@interface
- java注释@interface
- Java注释@interface的用法
- Java-注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- java注释@interface的用法
- java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- Java注释@interface的用法
- ORACLE创建按月和按天的自动递增分区
- Android开发之关于屏幕的最全工具类
- 前端js得到当前页面的url信息方法(JS获取当前网址信息)
- 哈工大语言云(LTP)本地安装使用及Python调用
- 求解偏微分方程开源有限元软件deal.II学习--Step 1
- Java注释@interface
- javascript 显示当前时间 练习01
- logstash 处理nginx 错误日志
- error no resource identifier found for attribute 'indeterminateTint' in package 'android'
- html5移动端:元素拖动/触控touch(js)(jquery)
- 国内最前沿的科技——室内导航技术发展及其现状
- ADO.NET Entity Framework(EF)
- HttpURLConnection使用:
- requery 与普通js 格式区别