java 注解开发_Java自定义注解开发

一、背景

最近在自己搞一个项目时,遇到可需要开发自定义注解的需求,对于没有怎么关注这些java新特性的来说,比较尴尬,索性就拿出一些时间,来进行研究下自定义注解开发的步骤以及使用方式。今天在这里记下,方便以后学习复习以及分享给有需要的小伙伴们~

二、注解基本概念

什么是注解?

注解就是某种注解类型的一个实例,我们可以用它在某个类上进行标注,这样编译器在编译我们的文件时,会根据我们自己设定的方法来编译类。

注解的分类有哪些?

7187030490a5657d1b11666baf0269c4.png

由上图可知:注解共分为:标记注解、标准元注解、一般注解三类。

注:Deprecated注解,除了多个删除线,并没有什么拦截功能。

标准元注解详解

标准元注解是自定义注解的注解,主要包含4个,都位于java.lang.annotation包中,我们创建自定义注解时会用到4个标准元注解。它们的名称以及含义如下:

1. @Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。是一个标记注解,没有成员。

2. @Inherited:是一个标记注解阐述了某个被标注的类型是被继承的。使用了@Inherited修饰的注解类型被用于一个class时该class的子类也有了该注解。

3. @Retention:定义了该注解的生命周期:某些注解仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的注解可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为注解与class在使用上是被分离的)。使用这个元注解可以对自定义注解的“生命周期”进行限制。

生命周期策略枚举

RetentionPolicy.RUNTIME 注解会在class字节码文件中存在,在运行时可以通过反射获取到。

RetentionPolicy.CLASS 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得。

RetentionPolicy.SOURCE 注解仅存在于源码中,在class字节码文件中不包含。

4. @Target:说明了注解所修饰的对象范围:注解可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。

修饰范围枚举

ElementType.CONSTRUCTOR  作用于构造器

ElementType.FIELD  作用于域/属性

ElementType.LOCAL_VARIABLE  用于描述局部变量

ElementType.METHOD  作用于方法

ElementType.PACKAGE   用于描述包

ElementType.PARAMETER   用于描述参数

ElementType.TYPE   用于描述类、接口(包括注解类型) 或enum声明,最常用

三、开发自定义注解demo

1.开发自定义类注解

1 packagecom.hafiz.zhang.annotation;2

3 importjava.lang.annotation.Documented;4 importjava.lang.annotation.ElementType;5 importjava.lang.annotation.Retention;6 importjava.lang.annotation.RetentionPolicy;7 importjava.lang.annotation.Target;8

9 /**

10 *@authorhafiz.Zhang11 * @Date 2016年5月18日 下午1:58:1112 * @Description 自定义类注解13 */

14 @Documented //定义可以被文档工具文档化

15 @Retention(RetentionPolicy.RUNTIME)//声明周期为runtime,运行时可以通过反射拿到

16 @Target(ElementType.TYPE)//注解修饰范围为类、接口、枚举

17 public @interfaceClassAnnotation {18 public String name() default "defaultService";19 public String version() default "1.1.0";20 }

2.自定义方法注解

1 packagecom.hafiz.zhang.annotation;2

3 importjava.lang.annotation.Documented;4 importjava.lang.annotation.ElementType;5 importjava.lang.annotation.Retention;6 importjava.lang.annotation.RetentionPolicy;7 importjava.lang.annotation.Target;8

9 importcom.hafiz.zhang.annotation.en.MethodTypeEnum;10

11 /**

12 *@authorhafiz.Zhang13 * @Date 2016年5月18日 下午1:58:2614 * @Description 自定义方法注解15 */

16 @Documented17 @Retention(RetentionPolicy.RUNTIME)18 @Target(ElementType.METHOD)19 public @interfaceMethodAnnotation {20 public String name() default "defaultName";21 public MethodTypeEnum type() defaultMethodTypeEnum.TYPE1;22 }

3.自定义域注解

1 packagecom.hafiz.zhang.annotation;2

3 importjava.lang.annotation.Documented;4 importjava.lang.annotation.ElementType;5 importjava.lang.annotation.Retention;6 importjava.lang.annotation.RetentionPolicy;7 importjava.lang.annotation.Target;8

9 /**

10 *@authorhafiz.Zhang11 * @Date 2016年5月18日 下午1:58:3712 * @Description 自定义域注解13 */

14 @Documented15 @Target(ElementType.FIELD)16 @Retention(RetentionPolicy.RUNTIME)17 public @interfaceFieldAnnotation {18 public String name() default "defaultName";19 public String value() default "defaultValue";20

21 }

4.方法类型枚举类

1 packagecom.hafiz.zhang.annotation.en;2

3 /**

4 *@authorhafiz.Zhang5 * @Date 2016年5月18日 下午1:59:026 * @Description 方法类型枚举类7 */

8 public enumMethodTypeEnum {9 TYPE1,TYPE210 }

5.测试注解Bean

1 packagecom.hafiz.zhang.annotation.bean;2

3 importcom.hafiz.zhang.annotation.ClassAnnotation;4 importcom.hafiz.zhang.annotation.FieldAnnotation;5 importcom.hafiz.zhang.annotation.MethodAnnotation;6 importcom.hafiz.zhang.annotation.en.MethodTypeEnum;7

8 /**

9 *@authorhafiz.Zhang10 * @Date 2016年5月18日 上午11:59:3711 * @Description 测试使用的bean12 */

13@ClassAnnotation(name="personBean", version="1.2.1")14 public classPerson {15 @FieldAnnotation(name="description", value="This is my personal annotation")16 privateString description;17

18 publicString getDescription() {19 returndescription;20 }21

22 public voidsetDescription(String description) {23 this.description =description;24 }25 @MethodAnnotation(name="sayHello", type = MethodTypeEnum.TYPE2)26 public voidsayHello() {27 System.out.println("Hello Annotation!");28 }29 }

6.自定义类注解测试类

1 packagecom.hafiz.zhang.annotation.test;2

3 importcom.hafiz.zhang.annotation.ClassAnnotation;4 importcom.hafiz.zhang.annotation.bean.Person;5

6 /**

7 *@authorhafiz.Zhang8 * @Date 2016年5月18日 上午11:56:349 * @Description 测试类注解10 */

11 public classTestClassAnnotation {12

13 private static Person person = newPerson();14

15 public static voidmain(String[] args) {16 Class> clazz =person.getClass();17 //因为注解是作用于类上面的,所以可以通过isAnnotationPresent来判断是否是一个具有指定注解的类

18 if(clazz.isAnnotationPresent(ClassAnnotation.class)) {19 System.out.println("This is a class with annotation ClassAnnotation!");20 //通过getAnnotation可以获取注解对象

21 ClassAnnotation annotation = clazz.getAnnotation(ClassAnnotation.class);22 if(null !=annotation) {23 System.out.println("BeanName = " +annotation.name());24 System.out.println("BeanVersion = " +annotation.version());25 }else{26 System.out.println("the annotation that we get is null");27 }28 }else{29 System.out.println("This is not the class that with ClassAnnotation");30 }31 }32 }

运行结果:

8e3e2f536839d8345f7e62349952ee77.png

7.自定义方法注解测试类

1 packagecom.hafiz.zhang.annotation.test;2

3 importjava.lang.reflect.Method;4

5 importcom.hafiz.zhang.annotation.MethodAnnotation;6 importcom.hafiz.zhang.annotation.bean.Person;7

8 /**

9 *@authorhafiz.Zhang10 * @Date 2016年5月18日 下午12:11:1111 * @Description 测试方法注解12 */

13 public classTestMethodAnnotation {14

15 private static Person person = newPerson();16

17 public static void main(String[] args) throwsException {18 Class> clazz =person.getClass();19 //因为是注解到method上的,所以首先要获取这个方法

20 Method method = clazz.getDeclaredMethod("sayHello");21 if(method.isAnnotationPresent(MethodAnnotation.class)) {22 System.out.println("===This is a method with a annotation:MethodAnnotation===");23 //通过getAnnotation可以获取注解对象

24 MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class);25 if(null !=annotation) {26 System.out.println("MethodName = " +annotation.name());27 System.out.println("MethodType = " +annotation.type());28 }else{29 System.out.println("the annotation that we get is null");30 }31 }else{32 System.out.println("This is not the class that with MethodAnnotation");33 }34 }35 }

运行结果:

561d3bd92154569f205203754d6c3325.png

8.自定义域注解测试类

1 packagecom.hafiz.zhang.annotation.test;2

3 importjava.lang.reflect.Field;4

5 importcom.hafiz.zhang.annotation.FieldAnnotation;6 importcom.hafiz.zhang.annotation.bean.Person;7

8 /**

9 *@authorhafiz.Zhang10 * @Date 2016年5月18日 下午12:17:4911 * @Description 测试域注解12 */

13 public classTestFieldAnnotation {14

15 private static Person person = newPerson();16

17 public static void main(String[] args) throwsException {18 Class> clazz =person.getClass();19 //因为是注解到Field上的,所以首先要获取这个字段

20 Field field = clazz.getDeclaredField("description");21 //判断这个Field上是否有这个注解

22 if(field.isAnnotationPresent(FieldAnnotation.class)) {23 System.out.println("===This is a field with annotation:FieldAnnotation!===");24 //如果有这个注解,则获取注解类

25 FieldAnnotation annotation = field.getAnnotation(FieldAnnotation.class);26 if(null !=annotation){27 System.out.println("before set the value is:" +person.getDescription());28 //通过反射给私有变量赋值

29 field.setAccessible(true);30 field.set(person, annotation.value());31 System.out.println("after set the value is:" +person.getDescription());32 }else{33 System.out.println("the annotation that we get is null");34 }35 }else{36 System.out.println("This is not the class that with FieldAnnotation");37 }38 }39 }

运行结果:

1efcfd16f026697cc3e922f6467897e7.png

附:demo项目结构图

75506414de49188d6da2544ab1510777.png

以上就是本人对自定义注解开发的理解以及开发测试了,如有错误希望大家能够批评指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值