参考:java技术手册
参考:https://blog.csdn.net/testcs_dn/article/details/78604547
java有两种特殊形式的类型,在java类型系统中扮演着特定的角色。这两种类型是枚举类 型(enumerated type)和注解类型(annotation type)。
本文介绍注解。
一、什么是注解
注解是一种特殊的接口。如名称所示,其作用是注解 Java 程序的某个部分。
例如 @Override 注解。在前面的一些示例中你可能见到过这个注解,想知道它有什么作用。
简单来说,什么作用也没有。这个答案或许会让你感到诧异。
说得稍微详细一点儿,注解没有直接作用,@Override 只是为注解的方法提供额外的信息,注明这个方法覆盖了超类中的方法。
注解能为编译器和集成开发环境(Integrated Development Environment,IDE)提供有用的提示。
如果开发者把方法的名称拼写错了,而这个方法本来是要覆盖超类的方法,那么,在这个名称拼错的方法上使用 @Override 注解,可以提醒编译器什么地方出错了。
注解不能改变程序的语义,只能提供可选的元信息。严格说来,这意味着注解不能影响程序的执行,只能为编译器和其他预执行阶段提供信息。
Java 平 台 在 java.lang 中 定 义 了 为 数 不 多 的 基 本 注 解。 一 开 始 只 支 持:
@Override:注明方法是覆盖的
@Deprecated :注明方法废弃了
@SuppressWarnings:静默编译器生成的警告。
后来,Java 7 增加了 :
@SafeVarargs(为变长参数方法提供增强的警告静默功能)
Java 8 增 加了
@FunctionalInterface。表示接口可以用作 lambda 表达式的目标。
和普通的接口相比,注解有些特殊的特性:
• 都(隐式)扩展 java.lang.annotation.Annotation 接口;
• 不能泛型化;
• 不能扩展其他接口;
• 只能定义没有参数的方法;
• 不能定义会抛出异常的方法;
• 方法的返回类型有限制;
• 方法可以有一个默认返回值。
二、自定义注解
开发者可以使用 @interface 关键字自定义新的注解类型,与定义类和接口的方式差不多。
自定义注解的关键是使用“元注解”。元注解是特殊的注解,用来注解新(自定义)注解类型的定义。
元注解在 java.lang.annotation 包中定义。开发者使用元注解指定新的注解类型能在哪里使用,以及编译器和运行时如何处理注解。
创建新的注解类型时,必须使用两个基本的元注解@Target 和 @Retention。这两个注解接受的值都在枚举中定义。
@Target:元注解指明自定义的新注解能在 Java 源码的什么地方使用。可用的值在枚举 ElementType 中 定 义, 包 括:TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_ VARIABLE、ANNOTATION_TYPE、PACKAGE、TYPE_PARAMETER 和 TYPE_USE。
@Retention: 指明 javac 和 Java 运行时如何处理自定义的注解类型。可使用的值有三个,在枚举 RetentionPolicy 中定义。
• SOURCE 使用这个保留原则的注解,编译时会被 javac 丢弃。
• CLASS 表示注解会出现在类文件中,但运行时 JVM 无法访问。这个值很少使用,但有时会在 JVM 字节码的离线分析工具中见到。
• RUNTIME 表示用户的代码在运行时(使用反射)能访问这个注解。
示例:如下这是个简单的注解,名为 @Nickname。开发者使用这个注解为方法指定一个昵称,运行时使用反射可以找到这个方法。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Nickname {
String[] value() default {};
}
定义注解——先指明注解能出现在哪里,然后是保留原则,最后是注解的名称。因为我们要给一个方法起昵称,所以还要在这个注解上定义一个方法。
除了两个基本的元注解之外,还有两个元注解:@Inherited 和 @Documented。实际使用中很少见到这两个注解,它们的详细说明参见 Java 平台的文档。
三、类型注解
Java 8 为枚举 ElementType 添加了两个新值:TYPE_PARAMETER 和 TYPE_USE。添加这两个值 后,注解能在以前不能出现的地方使用了,例如使用类型的所有地方。现在,开发者可以编写如下的代码:
@NotNull
String safeString = getMyString();
@NotNull 传达的额外类型信息可在特殊的类型检查程序中使用,用于检测问题(对这个例 子来说,可能抛出 NullPointerException 异常),还能执行额外的静态分析。Java 8 基本版自带了一些插入式类型检查程序,还提供了一个框架,开发者和库的作者可以使用这个框 架自己编写类型检查程序。