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());
        }
    }
    
  • 相关阅读:
    Windows Server 2003下ASP.NET无法识别IE11的解决方法
    SQL Server2005中使用XML-数据类型、查询与修改
    连接SQLServer时提示“但是在登录前的握手期间发生错误。 (provider: SSL Provider, error: 0
    无法将类型为 excel.applicationclass 的 com 强制转换为接口类型 的解决方法。
    C# WinForm使用Aspose.Cells.dll 导出导入Excel/Doc 完整实例教程
    技巧 获取电脑硬件信息 -转发
    浏览器无需下载插件 解决网页长截图的小技巧 -转发
    note 9 列表、时间复杂度、排序
    note 8 字符串
    note 7 递归函数
  • 原文地址:https://www.cnblogs.com/wt20/p/11801814.html
Copyright © 2011-2022 走看看