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