Java 8——重复注解和注解的作用范围的扩大化
一.重复注解
在某些情况下,希望将相同的注解应用于声明或类型用途。从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——重复注解和注解的作用范围的扩大化的更多相关文章
- JAVA中如何定义自定义注解
了解注解 注解是Java1.5,JDK5.0引用的技术,与类,接口,枚举处于同一层次 .它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释 . 在Java中,自带 ...
- Java注解(1)-注解基础
注解(Annotation)是在JAVA5中开始引入的,它为在代码中添加信息提供了一种新的方式.注解在一定程度上把元数据与源代码文件结合在一起,正如许多成熟的框架(Spring)所做的那样.那么,注解 ...
- Effective Java 第三版——39. 注解优于命名模式
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 【Java编程思想笔记】注解--元注解
参考文章:(小白的小小白的白 )https://blog.csdn.net/weixin_42315600/article/details/80630669 https://www.cnblogs.c ...
- Java编程思想学习笔记——注解
前言 在Android开发的过程中,我们为了减少重复代码的编写,会使用类似ButterKnife,AndroidAnnotations 这类依赖注解库.代码示例如下: //不使用 Button btn ...
- Java反射API研究(1)——注解Annotation
注解在表面上的意思,只是标记一下这一部分,最好的注解就是代码自身.而在java上,由于注解的特殊性,可以通过反射API获取,这种特性使得注解被广泛应用于各大框架,用于配置内容,代替xml文件配置. 要 ...
- 夯实Java基础(十七)——注解(Annotation)
1.注解概述 从JDK5.0开始,Java增加对元数据(MetaData)的支持,也就是注解(Annotation).其实我们早就已经接触过注解了,例如我们经常在Java代码中可以看到 “@Overr ...
- java8-13-默认方法 静态方法 重复注解 类型注解
java8增加默认方法 静态方法 重复注解 类型注解 1.默认方法 default修饰 为什么要有这个特性? 当修改接口时候,需要修改全部实现该接口的类.为了解决这个问题,所以引进默认方法 ...
- 大数据JavaWeb之java基础巩固----Junit&反射&注解
最近打算从0开始学学大数据,目前的主业是Android开发,但是当年毕业之后其实是搞J2EE的,所以打算没事又来拓展一下后台的技能,扩宽一下自己的知识体系对于自己的未来也能够多一些可能,另外大数据的一 ...
随机推荐
- js中的宏任务与微任务
如果你已经知道了js中存在宏任务和微任务,那么你一定已经了解过promise了.因为在js中promise是微任务的一个入口. 先来看一道题: setTimeout(function(){ conso ...
- 白话OAuth2用户认证及鉴权标准流程
一.OAuth2需求场景 在说明OAuth2需求及使用场景之前,需要先介绍一下OAuth2授权流程中的各种角色: 资源拥有者(User) - 指应用的用户 认证服务器 (Authorization S ...
- 华为OSPF与ACL综合应用
一. 实验拓扑图 二.实验要求 1.企业内网运行OSPF路由协议,区域规划如图所示:2.财务和研发所在的区域不受其他区域链路不稳定性影响:3.AR1.AR2.AR3只允许被IT登录管理:4.YF和CW ...
- React、React Native面试题
1.React Native相对于原生的ios和Android有哪些优势. react native一套代码可以开发出跨平台app, 减少了人力.节省了时间.避免了 iOS 与 Android 版本发 ...
- cf round 598div3 D.Binary String Minimizing
题目:https://codeforces.com/contest/1256/problem/D 题意:给你长度为n的01串,能将任意两相邻字符交换k次,求最小字典序的交换结果. 思路:贪心...甚至 ...
- 2018 牛客国庆集训派对Day4 - H 树链博弈
链接:https://ac.nowcoder.com/acm/contest/204/H来源:牛客网 题目描述 给定一棵 n 个点的树,其中 1 号结点是根,每个结点要么是黑色要么是白色 现在小 Bo ...
- BZOJ1014 火星人的prefix
火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字 ...
- ARTS-S sed指定行添加
sed -i 's#^AAAA.*#&BBBB#g' a.txt 在以AAA开始的行懂添加BBBB
- 【VMware】The VMX process exited permaturely
问题现象: 开启虚拟机时出现如图问题:虚拟机退出过早 解决方法: 以管理员身份运行cmd,输入netsh winsock reset ,回车然后重启
- C语言中表达n次方
C语言中表达n次方可以用pow函数. 函数原型:double pow(double x, double y) 功 能:计算x^y的值 返 回 值:计算结果 举例: double a; a = p ...