Java自定义注解学习

Posted 清风拂来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java自定义注解学习相关的知识,希望对你有一定的参考价值。

 

1.定义一个枚举类,后面自定义注解时使用

 1 package cn.tx.annotation.enums;
 2 /**
 3  * 定义枚举类型
 4  * @author Administrator
 5  *
 6  */
 7 public enum HttpMethod {
 8 
 9     GET,POST,PUT,INPUT,DELETE;
10 }

2. 自定义一个注解 AnnoTest 

 1 package cn.tx.annotation;
 2 
 3 import java.lang.annotation.Documented;
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Retention;
 6 import java.lang.annotation.RetentionPolicy;
 7 import java.lang.annotation.Target;
 8 
 9 import cn.tx.annotation.enums.HttpMethod;
10 
11 /**
12  * 1.自定义注解,自动实现了java.lang.Annotation接口
13  * @author Administrator
14  * 2.注解内部可以定义值,这里的值既不是属性,也不是方法
15  * 3.语法:数据类型      值的名字();
16  * 4.注解的意义:当非标识性注解(内部有值的注解)标注在方法上时,当方法被反射调用时,注解才有意义
17  * 5.@Retention 注解
18  * @Retention(RetentionPolicy.RUNTIME)
19  * @Target(ElementType.ANNOTATION_TYPE) public @interface Retention {
20  *                                      RetentionPolicy value(); }
21  *                                      RetentionPolicy:注解的策略
22  * RetentionPolicy.CLASS 表示这个注解能被编译到class文件里,但是运行时不参与运行
23  * 6.@Target注解——指示注解类型所适用的程序元素的种类
24  * @Documented
25     @Retention(RetentionPolicy.RUNTIME)
26     @Target(ElementType.ANNOTATION_TYPE)
27     public @interface Target {
28     ElementType[] value();
29     ElementType是一个枚举类型
30     }
31  *  7. @Target @Retention 只能用在注解的定义上面
32  *  8.@Documented 指明该注解将被包含在javadoc中  
33  */
34 
35 //ElementType.METHOD,表示AnnoTest只能放在方法上面,不能放在类,属性等其他上面
36 @Target(value = { ElementType.METHOD,ElementType.TYPE })  
37 @Retention(value = RetentionPolicy.RUNTIME)
38 public @interface AnnoTest {
39 
40     String value();//这里定义了值,在使用注解的地方,就得加上这个值
41     
42 //    Class[]/*String[]*/ location();
43 
44 //    HttpMethod method();
45         
46 }
47 
48 
49 // enum ElementType {
50 //    /**类,接口,枚举声明 Class, interface (including annotation type), or enum declaration */
51 //    TYPE,
52 //    /**字段声明,包括枚举常量   Field declaration (includes enum constants) */
53 //    FIELD,
54 //    /**方法声明   Method declaration */
55 //    METHOD,
56 //    /** Parameter declaration */
57 //    PARAMETER,
58 //    /** 构造方法声明  Constructor declaration */
59 //    CONSTRUCTOR,
60 //    /**局部变量声明  Local variable declaration */
61 //    LOCAL_VARIABLE,
62 //    /**注解类型声明   Annotation type declaration */
63 //    ANNOTATION_TYPE,
64 //    /**包声明    Package declaration */
65 //    PACKAGE
66 //}

3.  定义一个Claculate类,对方法使用自定义注解(前提是AnnoTest 注解 设置的@Target(value = { ElementType.METHOD,ElementType.TYPE })  ,也就是该注解能被使用在方法上面。)

 1 package cn.tx.annotation.test;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Target;
 5 
 6 import cn.tx.annotation.AnnoTest;
 7 
 8 public class Caculate {
 9 //    @AnnoTest(value = "sss") 
10     //AnnoTest注解中定义了@Target(value = { ElementType.METHOD,ElementType.TYPE }) 
11     //如果在属性a上面加@AnnoTest注解,会报:The annotation @AnnoTest is disallowed for this location
12     private int a;
13 
14     @AnnoTest(value = "相加的结果是:")
15     public int add(int a,int b){
16         return a+b;
17 }
18 
19 }

4. junit测试类:

 1 package cn.tx.annotation.test;
 2 
 3 import java.lang.annotation.Documented;
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Retention;
 6 import java.lang.annotation.RetentionPolicy;
 7 import java.lang.annotation.Target;
 8 import java.lang.reflect.Method;
 9 import java.util.ArrayList;
10 import java.util.List;
11 
12 import cn.tx.annotation.AnnoTest;
13 import cn.tx.annotation.enums.HttpMethod;
14 
15 /**
16  * 常用的表标识性注解:@Test @Override @SuppressWarnings
17  * 
18  * @author Administrator
19  * 
20  */
21 public class Test {
22 
23     @org.junit.Test
24     public void test() {
25 
26     }
27 
28     // @AnnoTest(value = "tst")
29     @Deprecated
30     // 过时,不建议使用的注解
31     public void method() {
32 
33     }
34 
35     /**
36      * @SuppressWarnings压制警告的注解 unchecked 不检查操作时的警告 rawtypes
37      *                          原始类型,也就是不使用泛型,在定义的时候压制泛型的警告
38      */
39     @SuppressWarnings( { "unchecked", "rawtypes" })
40     public void method1() {
41         @SuppressWarnings("unused")
42         List list = new ArrayList();// 不写泛型类型时,会出现黄色波浪线警告!
43         list.add("lisi");
44     }
45 
46     @org.junit.Test
47 //    @AnnoTest(value = "test", location = { String.class }, method = HttpMethod.GET)
48     // 非标识性注解的意义在于方法被反射调用时
49     public void method3() {
50 
51     }
52 
53     @org.junit.Test
54     public void testEnum() {
55         System.out.println(HttpMethod.GET); //执行该方法,控制台打印GET
56     }
57     
58     @org.junit.Test
59     public void testAdd(){
60         new Caculate().add(3, 5); //正常调用,add方法上面的注解不会起作用
61     }
62 
63     @org.junit.Test
64     public void testAdd1(){
65         //获取Caculate类的Class对象,进而获得一个实例,然后获取声明的方法及方法上的注解
66         Class<?> clazz = Caculate.class; 
67         try {
68             Object obj = clazz.newInstance();
69             //getFields()只能获取public的字段,包括父类的。getDeclaredFields()只能获取自己声明的各种字段,包括public,protected,private。
70             Method method = clazz.getDeclaredMethod("add", int.class,int.class);
71             //判断一个方法上面是否存在某个注解
72             boolean isPres = method.isAnnotationPresent(AnnoTest.class);
73             if(isPres){
74                 //根据一个类获取注解 ,即获得@AnnoTest
75                 AnnoTest annotation = method.getAnnotation(AnnoTest.class);
76                 //获得注解上的值
77                 String value = annotation.value(); //
78                 //反射的方式调用add()方法
79                 Object result = method.invoke(obj, 2,3);
80                 System.out.println(value+result); //控制台输出结果为: 相加的结果是:5
81                 //如果注解上的@Retention(value = RetentionPolicy.SOURCE),运行时时不会有结果的
82             }
83             
84         } catch (Exception e) {
85             e.printStackTrace();
86         }
87         
88     }
89 
90 }

 

以上是关于Java自定义注解学习的主要内容,如果未能解决你的问题,请参考以下文章

Java注解教程及自定义注解

Java注解教程:自定义注解示例,利用反射进行解析

java自定义注解学习_注解详解

Java自定义注解学习

如何在java web项目中添加自定义注解

Android APT注解处理器 ( Element 注解节点相关操作 )