JAVA注解

@Repeatable演示(附:注解思维导图)

例1:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(ResourcePaths.class)
public @interface ResourcePath {
    String value();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourcePaths {
    ResourcePath[] value();
}
@ResourcePath("/file/1")
@ResourcePath("/file/2")
public class RepeatableTest {
}
@ResourcePath("/file/3")
@ResourcePath("/file/4")
public class RepeatableSon extends  RepeatableTest {
}
public class Test {
    public static void main(String[] args) {
        Class clazz = RepeatableSon.class;
        //通过getAnnotationsByType方法获取所有重复注解
        ResourcePath[] annotationsByType = (ResourcePath[]) clazz.getAnnotationsByType(ResourcePath.class);
        ResourcePath[] annotationsByType2 = (ResourcePath[]) clazz.getDeclaredAnnotationsByType(ResourcePath.class);

        if (annotationsByType != null) {
            for (ResourcePath resourcePath : annotationsByType) {
                System.out.println("1:"+resourcePath.value());
            }
        }

        System.out.println("-----------------");

        if (annotationsByType2 != null) {
            for (ResourcePath resourcePath : annotationsByType2) {
                System.out.println("2:"+resourcePath.value());
            }
        }
        System.out.println("-----------------");
        System.out.println("使用getAnnotation的结果:"+clazz.getAnnotation(ResourcePath.class));
    }
}

输出的结果:

1:/file/3
1:/file/4
-----------------
2:/file/3
2:/file/4
使用getAnnotation的结果:null

通过上面的结果可以看出
使用Repeatable注解的重复注解是无法使用getAnnotation去获取注解信息的。

例2:

public class RepeatableSon2 extends RepeatableTest {
}
public class Test {
    public static void main(String[] args) {
        //通过getAnnotationsByType方法获取所有重复注解
        Class clazz2 = RepeatableSon2.class;
        ResourcePath[] annotationsByType3 = (ResourcePath[]) clazz2.getAnnotationsByType(ResourcePath.class);
        ResourcePath[] annotationsByType4 = (ResourcePath[]) clazz2.getDeclaredAnnotationsByType(ResourcePath.class);

        if (annotationsByType3 != null) {
            for (ResourcePath resourcePath : annotationsByType3) {
                System.out.println("3:"+resourcePath.value());
            }
        }

        System.out.println("-----------------");

        if (annotationsByType4 != null) {
            for (ResourcePath resourcePath : annotationsByType4) {
                System.out.println("4:"+resourcePath.value());
            }
        }

        System.out.println("使用getAnnotation的结果:"+clazz2.getAnnotation(ResourcePath.class));
    }
}

测试结果

-----------------
使用getAnnotation的结果:null

你会发现,并没有输出注解信息。这是因为@ResourcePath注解没有添加@Inherited注解,所以无法查询到注解信息。

例3:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Repeatable(ResourcePaths.class)
public @interface ResourcePath {
    String value();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ResourcePaths {
    ResourcePath[] value();
}

测试结果

3:/file/1
3:/file/2
-----------------
使用getAnnotation的结果:null

我们可以发现可以获取到父类的注解信息了。需要注意的是如果你用例1去添加@Inherited注解的话,依旧无法获取到父类的注解信息。其实我们查看源码会发现。只有子类没有注解的时候才会去获取父类的注解。

    default extends Annotation> T[] getAnnotationsByType(Class annotationClass) {
         //先调用getDeclaredAnnotationsByType方法
         T[] result = getDeclaredAnnotationsByType(annotationClass);
        //判断当前类获取到的注解数组是否为0
         if (result.length == 0 && 
             this instanceof Class && 
             //判断定义注解上是否使用了@Inherited元注解 
             AnnotationType.getInstance(annotationClass).isInherited()) { 
             //从父类获取
             Class superClass = ((Class) this).getSuperclass();
             if (superClass != null) {
                 // Determine if the annotation is associated with the
                 // superclass
                 result = superClass.getAnnotationsByType(annotationClass);
             }
         }

         return result;
     }

注解中定义了名为value的元素,在使用该注解时,如果该元素是唯一需要赋值的元素,则无需使用key=value的语法,而只需在括号内给出value元素所需的值即可。元素名必须为value。
JAVA注解_第1张图片

你可能感兴趣的:(java注解,java基础)