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