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 注解大都用在开发框架中吧,好了有关注解就学习那么多了,谢谢。