Java自定義注解


1.四個元注解解釋

@Target 表示作用的范圍

@Retention 表示生命周期范圍

@Documented 表示注解能被javadoc解析,默認注解是不被javadoc解析的

@Inherited 表示被注解的類的子類能繼承該注解。

2.獲取注解的方法(案例用了三個注解,更多注解百度查看API)

判斷對象是否有這個注解isAnnotationPresent(Class<? extends Annotation> annotationClass)
獲取對象的指定注解 getDeclaredAnnotation(Class<A> annotationClass)
獲取對象所有的注解 getDeclaredAnnotations()

案例一:熟悉@Target、@Retention和上面三個方法

 1 package com.jtfr.demo1;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 
 8 /**
 9  * 學生名字注解
10  * @author 陳康明 qq:1123181523
11  * @date 2019年2月27日
12  */
13 // @Target 表示注解使用的位置(類、字段等區分)
14 // TYPE 表示作用在 類、接口、注解、enum 上
15 @Target(ElementType.TYPE)
16 // @Retention 表示注解生命周期
17 // RUNTIME 表示在運行時期還有用,可以用於獲取注解的值,同時RUNTIME也是生命周期最長的一個。
18 @Retention(RetentionPolicy.RUNTIME)
19 public @interface StudentName {
20     /**
21      * 給了 default 值,注解上去的時候,可以不需要寫值了。
22      * @return
23      */
24     String name() default "";
25 }
 1 package com.jtfr.demo1;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 
 8 /**
 9  * 學生性別注解
10  * @author 陳康明 qq:1123181523
11  * @date 2019年2月27日
12  */
13 //@Target 表示注解使用的位置(類、字段等區分)
14 //TYPE 表示作用在 類、接口、注解、enum 上
15 @Target(ElementType.TYPE)
16 //@Retention 表示注解生命周期
17 //RUNTIME 表示在運行時期還有用,可以用於獲取注解的值,同時RUNTIME也是生命周期最長的一個
18 @Retention(RetentionPolicy.RUNTIME)
19 public @interface StudentSex {
20     /**
21      * 性別只有 男、女、不知道 三種情況,所以用 enum 類型。
22      */
23     public enum Sex{MAN, WOMAN, KNOW};
24     /**
25      * 給了 default 值,注解上去的時候,可以不需要寫值了。
26      * @return
27      */
28     Sex sex() default Sex.KNOW;
29     
30 }
 1 package com.jtfr.demo1;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 /**
 8  * 老師信息注解
 9  * @author 陳康明 qq:1123181523
10  * @date 2019年2月27日
11  */
12 //@Target 表示注解使用的位置(類、字段等區分)
13 //FIELD 表示作用 字段 上
14 @Target(ElementType.FIELD)
15 //@Retention 表示注解生命周期
16 //RUNTIME 表示在運行時期還有用,可以用於獲取注解的值,同時RUNTIME也是生命周期最長的一個
17 @Retention(RetentionPolicy.RUNTIME)
18 public @interface TeacherInfo {
19 
20     /**
21      * 課程科目假設就兩個,語文和數學 ,這樣明確的個數用枚舉表示。
22      * @return
23      */
24     public enum Course{LANGUAGE, MATHEMATICS};
25     Course course() default Course.LANGUAGE;
26     
27     /**
28      * 老師年齡, 一般默認值,字符串用"", 數字用 -1 這樣表示默認值,沒有寫
29      */
30     int age() default -1;
31 }
 1 package com.jtfr.demo1;
 2 
 3 import com.jtfr.demo1.StudentSex.Sex;
 4 import com.jtfr.demo1.TeacherInfo.Course;
 5 
 6 @StudentName(name="鈞天府人")
 7 @StudentSex(sex=Sex.MAN)
 8 public class Student {
 9 
10     @TeacherInfo(course=Course.LANGUAGE, age=18)
11     private String teacher;
12 }
 1 package com.jtfr.demo1;
 2 
 3 import java.lang.annotation.Annotation;
 4 import java.lang.reflect.Field;
 5 
 6 /**
 7  * 測試 注解 效果
 8  * @author 陳康明 qq:1123181523
 9  * @date 2019年2月27日
10  */
11 public class StudentTest {
12 
13     public static void main(String[] args) throws Exception{
14         Class<Student> cls = Student.class;
15         // 判斷類上是否有這個注解 isAnnotationPresent(Class<? extends Annotation> annotationClass)
16         if (cls.isAnnotationPresent(StudentName.class)) {
17             System.out.println("包含 StudentName 注解");
18             // 獲取類上的指定注解 getDeclaredAnnotation(Class<A> annotationClass)
19             StudentName studentName = (StudentName) cls.getDeclaredAnnotation(StudentName.class);
20             System.out.println("輸出注解信息:"+studentName);
21             System.out.println("姓名: "+studentName.name());
22         }
23         System.out.println("---------------------------------------");
24         // 獲取類上所有的注解 getDeclaredAnnotations()
25         Annotation[] annotations = cls.getDeclaredAnnotations();
26         for (Annotation annotation : annotations) {
27             System.out.println("輸出注解信息:"+annotation);
28             // instanceof 可以直接判斷 被轉成 父類的變量 是否是 子類 的實例
29             if (annotation instanceof StudentName) {
30                 System.out.println("姓名: "+((StudentName)annotation).name());
31             } else if(annotation instanceof StudentSex){
32                 System.out.println("性別: "+((StudentSex)annotation).sex());
33             }
34         }
35         System.out.println("---------------------------------------");
36         Field field = cls.getDeclaredField("teacher");
37         // 判斷 字段 上是否有這個注解isAnnotationPresent(Class<? extends Annotation> annotationClass)
38         if (field.isAnnotationPresent(TeacherInfo.class)) {
39             System.out.println("包含 TeacherInfo 注解");
40             // 字段獲取指定注解 和 上面一樣 getDeclaredAnnotation(Class<A> annotationClass)
41             TeacherInfo teacherInfo = field.getDeclaredAnnotation(TeacherInfo.class);
42             System.out.println("輸出注解信息:"+teacherInfo);
43             System.out.println("課程: "+teacherInfo.course());
44             System.out.println("年齡: "+teacherInfo.age());
45         }
46         System.out.println("---------------------------------------");
47         // 獲取 字段 上所有的注解 和 上面一樣 獲取類上所有的注解 getDeclaredAnnotations()
48         Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
49         for (Annotation annotation : declaredAnnotations) {
50             // 知道這里只有一個 注解 那就判斷一次就好了
51             if (annotation instanceof TeacherInfo) {
52                 TeacherInfo t = (TeacherInfo)annotation;
53                 System.out.println("直接輸出注解信息:"+t);
54                 System.out.println("課程: "+t.course());
55                 System.out.println("年齡: "+t.age());
56             }
57         }
58     }
59 }

執行輸出結果

案例二:@Inherited的使用

 1 package com.jtfr.demo2;
 2 
 3 import java.lang.annotation.Documented;
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Inherited;
 6 import java.lang.annotation.Retention;
 7 import java.lang.annotation.RetentionPolicy;
 8 import java.lang.annotation.Target;
 9 
10 // @Target 表示注解使用的位置(類、字段等區分)
11 // TYPE 表示作用在 類、接口、注解、enum 上
12 @Target(ElementType.TYPE)
13 // @Retention 表示注解生命周期
14 // RUNTIME 表示在運行時期還有用,可以用於獲取注解的值,同時 RUNTIME 也是生命周期最長的一個。
15 @Retention(RetentionPolicy.RUNTIME)
16 // @Documented 表示注解能被 javadoc 解析,默認注解是不被 javadoc 解析的
17 @Documented
18 // @Inherited 表示被注解的類的子類能繼承該注解。
19 @Inherited // 如果注釋了 B 就獲取不到 注解了。 可以自己注釋測試看一下結果
20 public @interface InheritedTest {
21 
22     String value() default "";
23 }
1 package com.jtfr.demo2;
2 
3 @InheritedTest("可以被子類獲取到")
4 public class A {
5 
6 }
1 package com.jtfr.demo2;
2 
3 public class B extends A {
4 
5 }
 1 package com.jtfr.demo2;
 2 
 3 /**
 4  * 測試 @Inherited 注解效果
 5  * @author 陳康明 qq:1123181523
 6  * @date 2019年2月27日
 7  */
 8 public class MainTest {
 9 
10     public static void main(String[] args) {
11         Class<B> cls = B.class;
12         if (cls.isAnnotationPresent(InheritedTest.class)) {
13             System.out.println("獲取到了父類上的注解");
14             System.out.println(cls.getAnnotation(InheritedTest.class).value());
15         }
16     }
17 }

執行輸出結果

3.組合注解,未完待續......

源碼

 https://files.cnblogs.com/files/jtfr/AnnotationDemo.rar

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM