一.重复注解

在某些情况下,希望将相同的注解应用于声明或类型用途。从Java SE 8发行版开始,重复注解使可以执行此操作。

例如,正在编写代码以使用计时器服务,该服务使能够在给定时间或某个计划上运行方法,类似于UNIX cron服务。现在,要设置计时器以在该月的最后一天和每个星期五晚上11:00 运行方法doPeriodicCleanup。要设置要运行的计时器,请创建一个@Schedule注解并将其应用于doPeriodicCleanup方法两次。第一次使用指定月份的最后一天,第二次使用指定星期五晚上11点,如下面的代码示例所示:

@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }

前面的示例将注解应用于方法。可以在使用标准注解的任何位置重复注解。例如,有一个用于处理未授权访问异常的类。使用一个@Alert注解为管理员注解并为管理员添加另一个注解:

@Alert(role="Manager")
@Alert(role="Administrator")
public class UnauthorizedAccessException extends SecurityException { ... }

出于兼容性原因,重复注解存储在由Java编译器自动生成的容器注解中。为了使编译器执行此操作,代码中需要两个声明。

第1步:声明可重复的注解类型

注解类型必须使用@Repeatable元注解标记。以下示例定义自定义@Schedule可重复注解类型:

import java.lang.annotation.Repeatable;

@Repeatable(Schedules.class)
public @interface Schedule {
String dayOfMonth() default "first";
String dayOfWeek() default "Mon";
int hour() default 12;
}

@Repeatable括号 中的元注解的值是Java编译器为存储重复注解而生成的容器注解的类型。在此示例中,包含注解类型是Schedules,因此重复@Schedule注解存储在@Schedules注解中。

将相同的注解应用于声明而不首先声明它是可重复的,这会导致编译时错误。

第2步:声明包含注解类型

包含注解类型必须具有value带数组类型的元素。数组类型的组件类型必须是可重复的注解类型。Schedules包含注解类型的声明如下:

public @interface Schedules {
Schedule[] value();
}

1.检索注解

Reflection API中有几种可用于检索注解的方法。返回单个注解的方法(例如 AnnotatedElement.getAnnotation(Class ))的行为未更改,因为如果存在所请求类型的一个注解,它们仅返回单个注解。如果存在多个所请求类型的注解,则可以通过首先获取其容器注解来获取它们。通过这种方式,遗留代码继续工作。Java SE 8中引入了其他方法,它们扫描容器注解以一次返回多个注解,例如 AnnotatedElement.getAnnotationsByType(Class )。请参阅 AnnotatedElement 有关所有可用方法的信息的类规范。

2.设计注意事项

设计注解类型时,必须考虑该类型注解的基数。现在可以使用注解零次,一次,或者,如果注解的类型被标记为@Repeatable多次,则不止一次。还可以通过使用@Target元注解来限制可以使用注解类型的位置。例如,可以创建只能在方法和字段上使用的可重复注解类型。仔细设计注解类型非常重要,以确保使用注解的程序员发现它尽可能灵活和强大。

二.类型注解和可插入类型系统

在Java SE 8发行版之前,注解只能应用于声明。从Java SE 8发行版开始,注解也可以应用于任何类型的使用。这意味着可以在任何使用类型的地方使用注解。使用where类型的一些示例是类实例创建表达式(new),强制转换,implements子句和throws子句。

  • 创建实例表达式时
new @Interned MyObject();
  • 类型转换:
myString = (@NonNull String) str;
  • 实现时:
class UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... }
  • 声明抛出异常:
void monitorTemperature() throws
@Critical TemperatureException { ... }

在元注解@Target中增加了作用类型:

/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER, /**
* Use of a type
*
* @since 1.8
*/
TYPE_USE

创建类型注解是为了支持改进的Java程序分析,以确保更强的类型检查。Java SE 8版本不提供类型检查框架,但它允许编写(或下载)类型检查框架,该框架实现为与Java编译器结合使用的一个或多个可插入模块。

例如,希望确保程序中的特定变量永远不会分配给null; 你想避免触发一个NullPointerException。可以编写自定义插件来检查此问题。然后,将修改代码以注解该特定变量,表明它从未分配给null。变量声明可能如下所示:

@NonNull String str;

当编译代码(包括NonNull命令行中的模块)时,编译器会在检测到潜在问题时输出警告,允许修改代码以避免错误。在更正代码以删除所有警告后,程序运行时不会发生此特定错误。

可以使用多个类型检查模块,其中每个模块检查不同类型的错误。通过这种方式,可以在Java类型系统的基础上构建,在希望的时间和地点添加特定的检查。

通过明智地使用类型注解和可插入类型检查器的存在,可以编写更强大且更不容易出错的代码。

在许多情况下,不必编写自己的类型检查模块。有第三方为你完成了这项工作。例如,可能希望利用华盛顿大学创建的Checker Framework。该框架包括一个NonNull模块,一个正则表达式模块和一个互斥锁模块。有关更多信息,请参阅 Checker Framework。

参考

Repeating Annotations

Type Annotations and Pluggable Type Systems

Java 8——重复注解和注解的作用范围的扩大化的更多相关文章

  1. JAVA中如何定义自定义注解

    了解注解 注解是Java1.5,JDK5.0引用的技术,与类,接口,枚举处于同一层次 .它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释 . 在Java中,自带 ...

  2. Java注解(1)-注解基础

    注解(Annotation)是在JAVA5中开始引入的,它为在代码中添加信息提供了一种新的方式.注解在一定程度上把元数据与源代码文件结合在一起,正如许多成熟的框架(Spring)所做的那样.那么,注解 ...

  3. Effective Java 第三版——39. 注解优于命名模式

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  4. 【Java编程思想笔记】注解--元注解

    参考文章:(小白的小小白的白 )https://blog.csdn.net/weixin_42315600/article/details/80630669 https://www.cnblogs.c ...

  5. Java编程思想学习笔记——注解

    前言 在Android开发的过程中,我们为了减少重复代码的编写,会使用类似ButterKnife,AndroidAnnotations 这类依赖注解库.代码示例如下: //不使用 Button btn ...

  6. Java反射API研究(1)——注解Annotation

    注解在表面上的意思,只是标记一下这一部分,最好的注解就是代码自身.而在java上,由于注解的特殊性,可以通过反射API获取,这种特性使得注解被广泛应用于各大框架,用于配置内容,代替xml文件配置. 要 ...

  7. 夯实Java基础(十七)——注解(Annotation)

    1.注解概述 从JDK5.0开始,Java增加对元数据(MetaData)的支持,也就是注解(Annotation).其实我们早就已经接触过注解了,例如我们经常在Java代码中可以看到 “@Overr ...

  8. java8-13-默认方法 静态方法 重复注解 类型注解

    java8增加默认方法 静态方法   重复注解 类型注解   1.默认方法 default修饰   为什么要有这个特性? 当修改接口时候,需要修改全部实现该接口的类.为了解决这个问题,所以引进默认方法 ...

  9. 大数据JavaWeb之java基础巩固----Junit&反射&注解

    最近打算从0开始学学大数据,目前的主业是Android开发,但是当年毕业之后其实是搞J2EE的,所以打算没事又来拓展一下后台的技能,扩宽一下自己的知识体系对于自己的未来也能够多一些可能,另外大数据的一 ...

随机推荐

  1. js中的宏任务与微任务

    如果你已经知道了js中存在宏任务和微任务,那么你一定已经了解过promise了.因为在js中promise是微任务的一个入口. 先来看一道题: setTimeout(function(){ conso ...

  2. 白话OAuth2用户认证及鉴权标准流程

    一.OAuth2需求场景 在说明OAuth2需求及使用场景之前,需要先介绍一下OAuth2授权流程中的各种角色: 资源拥有者(User) - 指应用的用户 认证服务器 (Authorization S ...

  3. 华为OSPF与ACL综合应用

    一. 实验拓扑图 二.实验要求 1.企业内网运行OSPF路由协议,区域规划如图所示:2.财务和研发所在的区域不受其他区域链路不稳定性影响:3.AR1.AR2.AR3只允许被IT登录管理:4.YF和CW ...

  4. React、React Native面试题

    1.React Native相对于原生的ios和Android有哪些优势. react native一套代码可以开发出跨平台app, 减少了人力.节省了时间.避免了 iOS 与 Android 版本发 ...

  5. cf round 598div3 D.Binary String Minimizing

    题目:https://codeforces.com/contest/1256/problem/D 题意:给你长度为n的01串,能将任意两相邻字符交换k次,求最小字典序的交换结果. 思路:贪心...甚至 ...

  6. 2018 牛客国庆集训派对Day4 - H 树链博弈

    链接:https://ac.nowcoder.com/acm/contest/204/H来源:牛客网 题目描述 给定一棵 n 个点的树,其中 1 号结点是根,每个结点要么是黑色要么是白色 现在小 Bo ...

  7. BZOJ1014 火星人的prefix

    火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字 ...

  8. ARTS-S sed指定行添加

    sed -i 's#^AAAA.*#&BBBB#g' a.txt 在以AAA开始的行懂添加BBBB

  9. 【VMware】The VMX process exited permaturely

    问题现象: 开启虚拟机时出现如图问题:虚拟机退出过早 解决方法: 以管理员身份运行cmd,输入netsh winsock reset ,回车然后重启

  10. C语言中表达n次方

    C语言中表达n次方可以用pow函数. 函数原型:double pow(double x, double y) 功    能:计算x^y的值 返 回 值:计算结果 举例: double a; a = p ...