Java 技术干货分享
如何快速获取或者判断一个类是否有某个注解呢?可以使用对象的 Class 信息来获取,下面是一个例子:
- public class AnnotationDemo {
- public static boolean hasAnnotation(AnnotatedElement element,
- Class<? extends Annotation> annotationType) {
- if (element.isAnnotationPresent(annotationType)) {
- return true;
- }
- return false;
- }
- public static void main(String[] args) {
- Annotations annotations = new Annotations();
- Class<?> cls = annotations.getClass();
- if (hasAnnotation(cls, AnnotationTestA.class)) {
- System.out.println("Annotation Test A");
- }
- if (hasAnnotation(cls, AnnotationTestB.class)) {
- System.out.println("Annotation Test B");
- }
- if (hasAnnotation(cls, AnnotationTestC.class)) {
- System.out.println("Annotation Test C");
- }
- }
- }
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @interface AnnotationTestA {}
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @interface AnnotationTestB {}
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @interface AnnotationTestC {}
- @AnnotationTestA
- @AnnotationTestB
- @AnnotationTestC
- class Annotations {}
在上面的例子中,hasAnnotation 方法的作用就是判断是否一个对象所属的类包含某个注解,可以分析一下具体的实现,首先,第一个参数类型为 AnnotatedElement,代表具体需要判断的对象 Class 信息,需要注意的是,Class 类实现了 AnnotatedElement 接口,所以传递一个 Class 对象给这个方法的第一个参数是合法的;第二个参数是注解类的 Class 信息,是需要检测的目标注解。可以看到,在代码中使用了 AnnotatedElement 的 isAnnotationPresent 方法来进行判断是否具有某个注解的功能,可以跟进去看一下具体的实现原理。
- default boolean isAnnotationPresent(Class < ?extends Annotation > annotationClass) {
- return getAnnotation(annotationClass) != null;
- }
- public < A extends Annotation > A getAnnotation(Class < A > annotationClass) {
- Objects.requireNonNull(annotationClass);
- return (A) annotationData().annotations.get(annotationClass);
- }
可以看一下 annotationData 方法的具体实现,参考下面的图片:
其中首先会判断是否具有需要的数据,以及是否符合要求,如果数据不存在或者过期了,那么就需要重新获取,重新获取数据的关键方法是 createAnnotationData,该方法的实现可以参考下面的代码:
annotationData 方法获取到的是一个 AnnotationData 对象,可以看一下 AnnotationData 类的定义:
- // annotation data that might get invalidated when JVM TI RedefineClasses() is called
- private static class AnnotationData {
- final Map < Class < ?extends Annotation > ,
- Annotation > annotations;
- final Map < Class < ?extends Annotation > ,
- Annotation > declaredAnnotations;
- // Value of classRedefinedCount when we created this AnnotationData instance
- final int redefinedCount;
- AnnotationData(Map < Class < ?extends Annotation > , Annotation > annotations, Map < Class < ?extends Annotation > , Annotation > declaredAnnotations, int redefinedCount) {
- this.annotations = annotations;
- this.declaredAnnotations = declaredAnnotations;
- this.redefinedCount = redefinedCount;
- }
- }
在 getAnnotation 方法中,该方法获取了 AnnotationData 字段的 annotations 字段来判断是否包含目标注解,更加深入的细节可以自行参考 Class 类的具体实现。本文是一个极短的 java 技术分享,提供一种获取一个对象的注解信息的思路,其实还有很多类型信息都是可以通过 Class 来获取到的,这方面的内容可以挖掘很多,日后会多往这方面做文章。
来源: http://www.jianshu.com/p/a449a2d1e371