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