详解Java8特性之重复注解

重复注解

注解(Annotation )是Java 5 推出来的,推出来后使用极其广泛,一些流行的框架基本都会用到注解实现一些功能,代替以前的配置方式,最典型的像Spring

在继续往下讲之前,我先声明你得知道注解的知识,我假设你已经掌握注解知识并能够自定义注解。

在Java 8 之前,同一个注解是不能在一个位置上重复使用的,例如我定义了一个注解@MyAnnotation

package edu.jyu.java8;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE) // 使用范围在类、接口和枚举
@Retention(RetentionPolicy.RUNTIME) // 生命周期在运行时期,可以进行反射操作
public @interface MyAnnotation {
    String value();// 定义一个属性值
}

然后定义了一个类Main,在该类上重复使用注解@MyAnnotation,编译时会报错

package edu.jyu.java8;

@MyAnnotation("Hello")
@MyAnnotation("World")
public class Main {

}

如果一定要在这个类上多次使用注解@MyAnnotation,按照以前的做法,我们需要定义一个注解容器,顾名思义是存放注解的,如我定义一个注解容器@MyAnnotationContainer,它的value属性是一个MyAnnotation数组

package edu.jyu.java8;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotationContainer {
    MyAnnotation[] value();
}

那么在Main类上我就可以通过注解容器让Main类多次使用@MyAnnotation注解

package edu.jyu.java8;

@MyAnnotationContainer({ @MyAnnotation("Hello"), @MyAnnotation("World") })
public class Main {

}

其实严格上来说,上面的Main并不是重复使用@MyAnnotation注解,而是使用@MyAnnotationContainer了。

而Java 8中提供了一个注解@Repeatable,可以对用户隐藏掉注解容器,我只需要在@MyAnnotation注解的定义上加上这个注解,如

package edu.jyu.java8;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE) // 使用范围在类、接口和枚举
@Retention(RetentionPolicy.RUNTIME) // 生命周期在运行时期,可以进行反射操作
@Repeatable(MyAnnotationContainer.class) // 重复注解,需要指定注解容器
public @interface MyAnnotation {
    String value();// 定义一个属性值
}

需要注意的是,@Repeatable注解是需要一个注解容器的。现在Main类中我就可以直接重复使用@MyAnnotation注解了

package edu.jyu.java8;

import java.util.Arrays;

@MyAnnotation("Hello")
@MyAnnotation("World")
public class Main {
    public static void main(String[] args) {
        Class<Main> clazz = Main.class;
        // 根据注解类型获取Main类上的所有注解
        MyAnnotation[] annotations = clazz.getAnnotationsByType(MyAnnotation.class);
        // 输出找到的所有注解
        Arrays.stream(annotations)//
                .forEach(System.out::println);

    }
}

main方法执行结果

@edu.jyu.java8.MyAnnotation(value=Hello)
@edu.jyu.java8.MyAnnotation(value=World)

输出找到的所有注解的代码是Java 8提供的Stream API和方法引用特性,还不了解的可以去看看我的其它Java 8特性文章

    原文作者:腹黑大壁花
    原文地址: https://blog.csdn.net/TimHeath/article/details/71374718
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞