注释是元数据的一种形式。它提供有关程序的数据,该数据不属于程序本身。注释对其注释的代码的操作没有直接影响。注释是在Java语言规范的第三版中以Java语言首次引入的,并首先在Java 5中实现。
注释具有多种用途,其中包括:
使用注释,我们能够将元数据信息添加到我们的源代码中-构建或部署信息,配置属性,编译行为或质量检查。
在这里,我将解释在何处可以使用批注,如何应用批注,Java平台标准版(Java SE API)中可用的预定义批注类型。
注释总是出现在被注释的代码之前,并且按照惯例,通常在其自己的行中以相同的级别缩进。
注释可能适用于包,类型(类,接口,枚举和注释类型),变量(类,实例和局部变量-包括在for或while循环中定义的变量),构造函数,方法和参数。
以最简单的形式,注释如下所示:
@Entity
at符号字符(@)向编译器指示后面是注释。在以下示例中,注释的名称为Override:
@Override
void myAnnotationUsageMethod() {
...
}
批注可以包含可以命名或未命名的elements,并且这些元素具有值:
@Author(
name = "Roland Hewage",
date = "2019/04/18"
)
class MyClass() { ... }
例如,可以在以下方法中使用它们:
@SuppressWarnings(value = "unchecked")
void myMethod() { ... }
注释可能包含仅由逗号分隔的名称/值对的元素。允许的类型是这些类型的原语,字符串,枚举,类,注释和数组,并且默认值不能为null:
@Author(name = "Roland",
created = "2020/04/16",
revision = 3,
reviewers = {"WSO2", "Shankar"})
public class SimpleAnnotationsTest {…}
当注释只有一个元素且其名称为value时,可以省略:
@SuppressWarnings(value = "unchecked")
void myMethod() { ... }
要么
@SuppressWarnings("unchecked")
void myMethod() { ... }
如果注释中没有元素,则可以省略括号,如前面的@Override示例所示。
@Override
void myAnnotationUsageMethod() { ... }
也可以在同一声明上使用多个注释:
@Author(name = "Roland Hewage")
@EBook
class MyClass { ... }
如果注释具有相同的类型,则称为重复注释:
@Author(name = "Roland Hewage")
@Author(name = "Rosy Buhat")
class MyClass { ... }
从Java SE 8版本开始,支持重复注释。
注释类型可以是Java SE API的java.lang或java.lang.annotation包中定义的类型之一。在前面的示例中,Override和SuppressWarnings是预定义的Java批注。也可以定义自己的注释类型。上一个示例中的Author和Ebook注释是自定义注释类型。
注释可以定义其某些或所有元素的默认值。具有默认值的元素可以从注释声明中省略。
例如,假设注释类型作者定义了修订的默认值(默认为1)和审阅者(默认为空的String数组),则以下两个注释声明是等效的:
@Author(name = "Roland",
created = "2018/04/18",
revision = 1,
reviewers = {})
public class SimpleAnnotationsTest() {…}
等于
@Author(name = "Roland", // defaults are revision 1
created = "2019/04/16") // and no reviewers
public class SimpleAnnotationsTest() {…}
注释可以应用于声明:类,字段,方法和其他程序元素的声明。当在声明上使用时,每个注释通常会按照惯例出现在自己的行上。
从Java SE 8发行版开始,注释也可以应用于类型的使用。这里有些例子:
类实例创建表达式:
new @Interned MyObject();
类型转换:
myString = (@NonNull String) str;
实现子句:
class UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... }
引发异常声明:
void monitorTemperature() throws
@Critical TemperatureException { ... }
这种形式的注释称为类型注释。
许多注释会替换代码中的注释。
假设开发人员传统上以提供重要信息的注释开始每个类的主体:
public class Generation3List extends Generation2List {
// Author: Roland Hewaage
// Date: 2019/04/16
// Current revision: 6
// Last modified: 2019/04/18
// By: Roland Hewage
// Reviewers: Alice, Bill, Cindy
// class code goes here
}
要使用注释添加相同的元数据,必须首先定义注释类型。这样做的语法是:
@interface ClassPreamble {
String author();
String date();
int currentRevision() default 1;
String lastModified() default "N/A";
String lastModifiedBy() default "N/A";
// Note use of array
String[] reviewers() default {};
}
批注类型定义看起来类似于接口定义,在该接口定义中,关键字interface前面带有at符号(@)(@ = AT,与批注类型一样)。注释类型是接口的一种形式。
先前的注释定义的主体包含注释类型元素声明,它们看起来很像方法。请注意,它们可以定义可选的默认值。
定义注释类型后,您可以使用该类型的注释,并在其中填充值,如下所示:
@ClassPreamble (
author = "Roxana Chatu",
date = "2018/06/23",
currentRevision = 6,
lastModified = "2018/09/12",
lastModifiedBy = "Roly Ross",
// Note array notation
reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {
// class code goes here
}
要使@ClassPreamble中的信息出现在Javadoc生成的文档中,必须使用@Documentedannotation注释@ClassPreamble定义:
// import this to use @Documented
import java.lang.annotation.*;
@Documented
@interface ClassPreamble {
// Annotation element definitions
}
Java SE API中预定义了一组注释类型。Java编译器使用某些注释类型,而某些注释类型适用于其他注释。
Java语言使用的注释类型
在java.lang中定义的预定义注释类型为@ Deprecated,@ Override和@SuppressWarnings。
1. @已弃用
@Deprecated注释指示已标记的元素已弃用,不应再使用。每当程序使用带有@Deprecated批注的方法,类或字段时,编译器都会生成警告。不推荐使用元素时,还应使用Javadoc @deprecated标记对其进行记录,如以下示例所示。
在Javadoc注释和注释中使用at符号(@)并非偶然:它们在概念上相关。另外,请注意,Javadoc标记以小写字母d开头,注释以大写字母D开头。
// Javadoc comment follows
/**
* @deprecated
* explanation of why it was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
2. @Override
@Override注释通知编译器该元素用于覆盖超类中声明的元素。
// mark method as a superclass method
// that has been overridden
@Override
int overriddenMethod() { }
虽然在重写方法时不需要使用此批注,但它有助于防止错误。如果标有@Override的方法未能正确覆盖其父类之一中的方法,则编译器将生成错误。
3. @SuppressWarnings
@SuppressWarnings批注告诉编译器禁止以其他方式生成的特定警告。在下面的示例中,使用了不赞成使用的方法,并且编译器通常会生成警告。但是,在这种情况下,注释会导致警告被抑制。
// use a deprecated method and tell
// compiler not to generate a warning
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
// deprecation warning
// - suppressed
objectOne.deprecatedMethod();
}
每个编译器警告都属于一个类别。Java语言规范列出了两类:不推荐使用和未选中。与泛型出现之前编写的旧代码进行交互时,可能会发生未经检查的警告。要禁止显示多类警告,请使用以下语法:
@SuppressWarnings({"unchecked", "deprecation"})
4. @SafeVarargs
@SafeVarargs批注应用于方法或构造函数时,声明该代码不会对其varargs参数执行潜在的不安全操作。使用此注释类型时,将抑制与varargs使用有关的未经检查的警告。
5. @FunctionalInterface
Java SE 8中引入的@FunctionalInterface批注指示类型声明旨在作为功能接口,如Java语言规范所定义。
自引入注释以来,许多库和框架已将注释合并到其较新的发行版中。通过在源代码中使用注释,这些库和框架减少了甚至消除了对配置文件的需求。
辉煌的例子可见于:
适用于其他注释的注释称为元注释。java.lang.annotation中定义了几种元注释类型。
1. @保留
@Retention注释指定标记的注释的存储方式:
2. @记录
@Documented注释表示,每当使用指定的注释时,都应使用Javadoc工具记录这些元素。(默认情况下,Javadoc中不包含注释。)
3. @Target
@Target批注标记了另一个批注,以限制该批注可以应用于哪种Java元素。目标注释将以下元素类型之一指定为其值:
4. @继承
@Inherited批注指示批注类型可以从超类继承。(默认情况下,这是不正确的。)当用户查询注释类型并且类没有该类型的注释时,将为该注释类型查询类的超类。该注释仅适用于类声明。
5. @可重复
Java SE 8中引入的@Repeatable注释表示可以将标记的注释多次应用于同一声明或类型使用.