zoukankan      html  css  js  c++  java
  • 元注解之@Repeatable

    简介

    @Repeatable注解从JDK 1.8开始引入,为了解决注解不能在同一个地方重复使用而出现的。在JDK 1.8以前,下面这段代码将不能通过编译。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Identity {
    
        String value();
    }
    
    // 不能重复使用
    @Identity("父亲")
    @Identity("教师")
    public class RepeatableTest {
    
    }
    
    

    使用

    先定义注解

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(Identities.class)
    @Documented
    public @interface Identity {
    
        String value();
    }
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Identities {
    
        Identity[] value();
    }
    
    

    为了使得@Identity注解可以重复使用,需要注意以下几点。

    • 在定义时用@Repeatable标记一个容器注解@Identities
    • 该容器注解@Identities必须要声明一个value方法,并且返回值是一个Identity[]类型,否则编译报错。

    测试类

    @Identity("父亲")
    @Identity("教师")
    public class RepeatableTest {
    
        public static void main(String[] args) {
            // 获取注解信息
            // 值得注意的是参数传的是Identities.class,而不是Identity.class。
            // 原因看下面原理介绍
            Identities identitiesAnnotation = RepeatableTest.class.
                getAnnotation(Identities.class);
            Identity[] identities = identitiesAnnotation.value();
            Arrays.stream(identities).forEach(identity -> 
               System.out.println(identity.value()));
        }
    }
    

    原理

    如果我们将编译后的RepeatableTest.class文件反编译下,将得到以下源代码。

    @Identities({@Identity("父亲"), @Identity("教师")})
    public class RepeatableTest {
        public RepeatableTest() {
        }
        
        // 省略main方法
    }
    

    可以看到重复使用@Identity注解其实是一个语法糖,这也是为什么上面getAnnotation方法传的参数是Identities.class的原因。继续使用Class类提供的方法做检测。

    @Identity("父亲")
    @Identity("教师")
    public class RepeatableTest {
    
        public static void main(String[] args) {
            // 返回false
            System.out.println(RepeatableTest.class.isAnnotationPresent(Identity.class));
            // 返回null
            System.out.println(RepeatableTest.class.getAnnotation(Identity.class));
            // 由此可见RepeatableTest类中确实没有被Identity直接注解。
            
            // 另外一种简便的方法获取注解信息
            // 使用getAnnotationsByType方法, 此方法为JDK 1.8新增
            Identity[] identities = RepeatableTest.class
                .getAnnotationsByType(Identity.class);
            Arrays.stream(identities).forEach(identity ->
                    System.out.println(identity.value()));
    
            Identities[] identitiesAnnotation = RepeatableTest.class.
                getAnnotationsByType(Identities.class);
            // 输出父亲
            System.out.println(identitiesAnnotation[0].value()[0].value());
        }
    }
    
  • 相关阅读:
    thymeleaf常用属性
    spring的jdbcTemplate的使用
    spring使用thymeleaf
    thymeleaf介绍
    struts2请求过程源码分析
    Git 学习笔记之(三)将本地工程导入到GitHub 仓库中
    spring boot 学习笔记(三)之 配置
    Zookeeper 学习笔记(一)之功能介绍
    Git 学习笔记之(一) 使用 git gui 从github上下载代码
    Linux 清理空间
  • 原文地址:https://www.cnblogs.com/wt20/p/11801814.html
Copyright © 2011-2022 走看看