一.重复注解

在某些情况下,希望将相同的注解应用于声明或类型用途。从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. 学习spring和spring mvc过程中遇到的一些问题

    以下仅为个人通过网上查找资料总结的内容,如有不对的地方欢迎提出: 注解: @Controller//表明本类是一个Controller @RequestMapping(value="/dem ...

  2. 第三章 学习Shader所需的数学基础(4)

    法线变换 法线(normal),也被称为法矢量(normal vector).在以前我们已经讲过如何使用变换矩阵来变换一个顶点或方向矢量,但法线是需要我们特殊处理的一种方向矢量.在游戏中,模型的顶点往 ...

  3. Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)

    View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇  ...

  4. io流函数略解(java)[一]

    背景 最近在做安卓的过程中,因为im app经常涉及到读取与写入的io问题,所以总结一下.下文使用的是java语言. 实践 材料: java eclipse 1.File 在操作系统中我们一般能看到的 ...

  5. .Neter所应该彻底了解的委托

    本文将通过引出几个问题来,并且通过例子来剖析C#中的委托以及用法,做抛砖引玉的作用 对于委托我发现大部分人都有以下问题,或者可能在面试中遇过这样的: 委托是不是相当于C/C++的函数指针? 委托究竟是 ...

  6. 转:FileSync plugin for Eclipse 安装注意事项 Eclipse文件同步插件

    习惯了使用MyEclipse,各种插件不用自己安装,觉得开发起来很方便,现在大家都用Eclipse了,还有不用Eclipse用更高级的,IT当然开发大型项目没人用UltraEdit吧,虽然是一个不错的 ...

  7. 让微信推送Jenkins构建消息

    Jenkins作为开发必备之神器,各家大小公司都在使用.Jenkins自身内置了基于邮件推送构建结果的功能.但是随着移动互联网的发展,邮件这玩意已经越来越少使用了,是否有一种办法能把jenkins构建 ...

  8. 洛谷 题解 P5595 【【XR-4】歌唱比赛】

    本蒟蒻又双叒叕被爆踩了. 考试时一遍过 其实这题还是很简单的,难度不会大于普及组T1. CSP 2019 RP++ 看开始看到题目,觉得特别长,不想看... 我来和你们分析分析题目,你们就都可以秒了. ...

  9. WWDC 2016 盛宴

    转自:http://www.jianshu.com/p/72dd8306c817 整理和维护人:pmstGitHub 链接:WWDC-2016-Feast目前只是整理官方给出的 WWDC 2016 视 ...

  10. React-Native项目在Android真机上调试

    目录 1.确保你的设备已经成功连接.可以终端输入adb devices来查看: 2.终端运行npm start 开启本地服务,成功后运行react-native run-android来在设备上安装并 ...