在上一篇有关Java注释的文章中,我概述了一个最近的用例,并为您提供了一些自定义注释的示例以及如何使用它们。

在本文中,我将更进一步,并为您提供一些自定义注释的示例,以及如何使用Java Reflection API处理这些自定义注释。 学习完本教程后,您应该对自定义注释可以提供的简单性和灵活性有了更好的了解。 因此,让我们深入研究代码!

自定义注释清单

我今天为示例代码创建了三个不同的注释,分别是DoItLikeThisDoItLikeThatDoItWithAWhiffleBallBat注释。 每个注释针对的是不同的元素类型,并且具有稍微不同的属性,因此我可以向您展示如何查找和相应地处理它们。

喜欢这个注释

DoItLikeThis注释针对ElementType TYPE,这使其仅可用于Java类型。 该批注具有三个可选元素description,action和一个布尔字段shouldDoItLikeThis。 如果在使用此批注时不为这些元素提供任何值,则它们将默认为指定的值。

package com.keyhole.jonny.blog.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** Annotation created for doing it like this.*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DoItLikeThis {/*** @return - The description.*/String description() default "";/*** @return - The action.*/String action() default "";/*** @return - Should we be doing it like this.*/boolean shouldDoItLikeThis() default false;}

像注释一样

DoItLikeThat注释是仅针对Java字段的注释。 此批注还具有一个类似的布尔元素,名称为ShouldDoItLikeThat,它没有指定默认值,因此在使用批注时是必选元素。 批注还包含一个定义为String数组的元素,该元素将包含应检查的用户角色列表。

package com.keyhole.jonny.blog.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** Annotation created for doing it like that* instead of like this.*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DoItLikeThat {/*** @return - Should we be doing it like that.*/boolean shouldDoItLikeThat();/*** @return - List of user roles that can do it like that.*/String[] roles() default{};}

DoWWithAWhiffleBallBat批注

DoItWithAWhiffleBallBat注释旨在仅与方法一起使用,并且与其他注释类似。 它也有一个类似的布尔元素,这个名字叫做shouldDoItWithAWhiffleBallBat。 还定义了另一个元素,该元素使用WhiffleBallBat枚举定义了可用的不同类型的Whiffle球棒,默认为经典的黄色经典Whiffle球棒。

package com.keyhole.jonny.blog.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** When you can't do it like this or do it like that,* do it with a whiffle ball bat.*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DoItWithAWhiffleBallBat {/*** @return - Should we be doing it with a whiffle ball bat.*/boolean shouldDoItWithAWhiffleBallBat() default false;/*** @return - Sweet, which type of whiffle ball bat?*/WhiffleBallBat batType() default WhiffleBallBat.YELLOW_PLASTIC;}

带注释的类

现在我们已经为示例定义了注释,我们需要几个类进行注释。 每个类都提供了使用指定元素以及依赖默认值的注释的示例用法。 还包括其他未注释的字段和方法,因此注释处理器不应对其进行处理。 这是两个示例类的源代码:

带注释的一类

package com.keyhole.jonny.blog.annotations;import java.util.Date;@DoItLikeThis
public class AnnotatedOne implements AnnotatedClass {@DoItLikeThat(shouldDoItLikeThat = false)private String field1;@DoItLikeThat(shouldDoItLikeThat = true, roles = { "admin", "root" })private String field2;private String field3;private Date dateDoneLikeThis;/* setters and getters removed for brevity */@DoItWithAWhiffleBallBat(batType = WhiffleBallBat.BLACK_PLASTIC, shouldDoItWithAWhiffleBallBat = true)public void doWhateverItIs() {// method implementation}public void verifyIt() {// method implementation}}

带注释的二级

package com.keyhole.jonny.blog.annotations;import java.util.Date;@DoItLikeThis(action = "PROCESS", shouldDoItLikeThis = true, description = "Class used for annotation example.")
public class AnnotatedTwo implements AnnotatedClass {@DoItLikeThat(shouldDoItLikeThat = true)private String field1;@DoItLikeThat(shouldDoItLikeThat = true, roles = { "web", "client" })private String field2;private String field3;private Date dateDoneLikeThis;/* setters and getters removed for brevity */@DoItWithAWhiffleBallBat(shouldDoItWithAWhiffleBallBat = true)public void doWhateverItIs() {// method implementation}public void verifyIt() {// method implementation}}

处理注释

使用反射来处理注释实际上非常简单。 对于您可以为其创建和应用注释的每种元素类型,这些元素上都有一些使用注释的方法。 您需要做的第一件事是检查元素以确定是否有任何注释或检查该元素是否存在特定注释。

每个元素类型Class,Field和Method都实现了AnnotatedElement接口,该接口定义了以下方法:

  • getAnnotations() –返回此元素上存在的所有注释,包括所有继承的注释。
  • getDeclaredAnnotations() –仅返回直接存在于此元素上的注释。
  • getAnnotation(Class <A>注记类) –返回指定注解类型的元素注解,如果找不到,则返回null。
  • isAnnotation() –如果要检查的元素是注释,则返回true。
  • isAnnotationPresent(Class <?Extends Annotation>注解类) –如果所检查的元素上存在指定的注解,则返回true。

在处理批注时,我们要做的第一件事是检查批注是否存在。 为此,我们将对批注处理进行以下检查:

if (ac.getClass().isAnnotationPresent(DoItLikeThis.class)) {// process the annotation, "ac" being the instance of the object we are inspecting}

找到所需的批注后,我们将获取该批注并为该批注进行任何处理。 至此,我们将可以访问注释的元素及其值。 请注意,没有任何用于访问注释元素的获取器或设置器。

DoItLikeThis anno = ac.getClass().getAnnotation(DoItLikeThis.class);System.out.println("Action: " + anno.action());System.out.println("Description: " + anno.description());System.out.println("DoItLikeThis:" + anno.shouldDoItLikeThis());

对于字段和方法,检查当前注释会略有不同。 对于这些类型的元素,我们需要遍历所有字段或方法以确定元素上是否存在注释。 您将需要从Class中获取所有字段或方法,遍历Field或Method数组,然后确定元素上是否存在注释。 看起来应该像这样:

Field[] fields = ac.getClass().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(DoItLikeThat.class)) {DoItLikeThat fAnno = field.getAnnotation(DoItLikeThat.class);System.out.println("Field: " + field.getName());System.out.println("DoItLikeThat:" + fAnno.shouldDoItLikeThat());for (String role : fAnno.roles()) {System.out.println("Role: " + role);}}}

结论

如您所见,创建自己的注释并进行处理非常简单。 在我提供的示例中,我们只是将元素的值输出到控制台或日志。 希望您能看到这些的潜在用途,并且将来可能会真正考虑创建自己的。 我在注释中看到的一些最佳用法是,它们替换一些配置代码或经常使用的通用代码,例如验证字段的值或将业务对象映射到Web表单。

最后,这是完整的源代码以及一个简单的Java主类来执行代码:

带注释的类处理器

package com.keyhole.jonny.blog.annotations;import java.lang.reflect.Field;
import java.lang.reflect.Method;public class AnnotatedClassProcessor {public void processClass(AnnotatedClass ac) {System.out.println("------Class Processing Begin---------");System.out.println("Class: " + ac.getClass().getName());if (ac.getClass().isAnnotationPresent(DoItLikeThis.class)) {// process the annotation, "ac" being the instance of the object we are inspectingDoItLikeThis anno = ac.getClass().getAnnotation(DoItLikeThis.class);System.out.println("Action: " + anno.action());System.out.println("Description: " + anno.description());System.out.println("DoItLikeThis:" + anno.shouldDoItLikeThis());System.out.println("------Field Processing---------");Field[] fields = ac.getClass().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(DoItLikeThat.class)) {DoItLikeThat fAnno = field.getAnnotation(DoItLikeThat.class);System.out.println("Field: " + field.getName());System.out.println("DoItLikeThat:" + fAnno.shouldDoItLikeThat());for (String role : fAnno.roles()) {System.out.println("Role: " + role);}}}System.out.println("------Method Processing---------");Method[] methods = ac.getClass().getMethods();for (Method method : methods) {if ( method.isAnnotationPresent(DoItWithAWhiffleBallBat.class)) {DoItWithAWhiffleBallBat mAnno = method.getAnnotation(DoItWithAWhiffleBallBat.class);System.out.println("Use WhiffleBallBat? " + mAnno.shouldDoItWithAWhiffleBallBat());System.out.println("Which WhiffleBallBat? " + mAnno.batType());}}}System.out.println("------Class Processing End---------");}
}

运行处理器

package com.keyhole.jonny.blog.annotations;public class RunProcessor {/*** @param args*/public static void main(String[] args) {AnnotatedClassProcessor processor = new AnnotatedClassProcessor();processor.processClass(new AnnotatedOne());processor.processClass(new AnnotatedTwo());}}

翻译自: https://www.javacodegeeks.com/2014/09/processing-java-annotations-using-reflection.html

使用反射处理Java批注相关推荐

  1. java word批注_使用反射处理Java批注

    java word批注 在上一篇有关Java注释的文章中,我概述了一个最近的用例,并为您提供了一些自定义注释的示例以及如何使用它们. 在本文中,我将更进一步,并为您提供一些自定义注释的示例,以及如何使 ...

  2. pdf.js批注_使用反射处理Java批注

    pdf.js批注 在上一篇有关Java注释的文章中,我概述了一个最近的用例,并为您提供了一些自定义注释的示例以及如何使用它们. 在本文中,我将更进一步,并提供一些自定义注释的示例,以及如何使用Java ...

  3. java 委托机制_通过反射实现Java下的委托机制代码详解

    简述 一直对Java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块API public Class Delegater()//空参构造,该类管理委托实例并 ...

  4. java委托机制教程_通过反射实现Java下的委托机制代码详解

    简述 一直对java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块api public class delegater()//空参构造,该类管理委托实例并 ...

  5. java word批注_编写Java批注

    java word批注 Java 批注的允许的属性类型刻意非常严格,但是允许的类型也可以使用一些简洁的复合批注类型. 考虑教程站点中的示例注释: package annotation; @interf ...

  6. Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持

    Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持,下面关于Java反射的描述,哪些是错误的:(          ) A Java反射主要涉及的类如C ...

  7. 【Java基础】RTTI与反射之Java

    一.引言 很多时候我们的程序可能需要在运行时识别对象和类的信息,比如多态就是基于运行时环境进行动态判断实际引用的对象.在运行时识别对象和类的信息主要有两种方式:1.RTTI,具体是Class对象,它假 ...

  8. Java 反射 C 反射调用 java 方法

    1. Java 反射 1.1 创建 Demo.java 类 public class Demo {public void hello(String str){System.out.println(st ...

  9. Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持,下面关于Java反射的描述,哪些是错误的:()

    例题 (多选)Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持,下面关于Java反射的描述,哪些是错误的:() A. Java反射主要涉及的类如Class, Method, Fi ...

最新文章

  1. 权重对生成对抗网络GAN性能的影响
  2. Linux shell逻辑运算
  3. python蟒蛇绘制步骤_如何用python绘制蟒蛇移动的样子-百度经验
  4. 天猫双11倒计时:80000瓶1499元53度飞天茅台将开放限量抢购
  5. 手机sstv解码软件_关于二维码扫描使用专业扫描设备和手机二维码扫描软件的区别?...
  6. 图像识别讲解 以一个简单的图像识别任务为例
  7. python 插入数据库 b“Incorrect syntax near ‘,‘.DB-Lib error message 20018
  8. MASM32汇编SDK安装
  9. Windows查看所有的端口
  10. 数据增强:模拟雨天算法Python
  11. python c语言实现_使用C语言为python编写动态模块(3)--在C中实现python中的类
  12. excel sumifs多条件求和
  13. ppt讲解中的过渡_PPT「过渡页」怎么设计才好看?
  14. 「兔了个兔」看我如何抓取兔兔图片到本地(附源码)
  15. 自我中心网络:科普+数据共享
  16. 计算梯度的三种方法: 数值法,解析法,反向传播法
  17. 计算机计算公式在哪,计算机的计算器在哪 自己的电脑上的计算器在哪里找
  18. VBA脚本实现痕迹保留、手写签名、电子印章的插件
  19. python对银行工作有用吗_银行工作真的很可怕吗?
  20. 【第108期】技术大牛都在看的10本书,找到了

热门文章

  1. win 7 mysql 1067_win7系统登陆MySQL服务出现1067错误的解决方法
  2. 可视化大屏设计尺寸_可视化大屏设计_酷炫不是最高效的大屏展示的唯一标准...
  3. 如何从文件系统中读取文件内容
  4. openapi_MicroProfile OpenAPI上的Swagger UI
  5. aws lambda_跑来跑去:假人与AWS Lambda的第一次接触
  6. java 平台级模块系统_Java平台模块系统公众审查未能通过
  7. kafka 发布订阅_在Kafka中发布订阅模型
  8. 戴尔集群监控与管理系统_监控与管理
  9. jit 和 jvm_关于JVM和JIT的一点点
  10. java状态模式和策略模式_Java状态和策略设计模式之间的差异