注释的主要好处不是来自使用 JDK 中已有的标准注释。同时,很少需要创建自己的注释。但如果我们正在开发一个大型系统或创建一个单独的库,那么在架构层面,实现我们自己的注释肯定会产生红利。

让我们尝试创建一个注释。

为此,创建一个文件,但不是写classinterface,而是写@interface。这将是我们注释的文件。注解的内部结构类似于接口。


public @interface Sum {
   int sum() default 0;
}

@interface表示这是一个注解,
default表示该参数将具有特定的默认值。

哒哒!我们创建了一个注释!理论上我们已经可以使用它了,但首先配置它会更好。

没有配置,我们的注释可以应用于任何东西(类、方法、属性等),所以此时使用它意义不大。看起来很奇怪,我们的注释需要用其他注释进行注释!

让我们从@Target开始。

@Target注释(自 Java 1.5 起相关)限制应用注释的能力。为了将使用限制在某个级别,我们需要将参数传递给@Target注释以指示它可以应用于哪些类型。以下是一些常用的类型:

@Target(ElementType.PACKAGE) 对于包裹
@Target(元素类型.TYPE) 上课
@Target(ElementType.CONSTRUCTOR) 对于构造函数
@Target(元素类型.METHOD) 对于方法
@Target(元素类型.FIELD) 对于类中的属性(变量)
@Target(元素类型.参数) 对于方法参数
@Target(ElementType.LOCAL_VARIABLE) 对于局部变量

如果您需要多种类型的注解,则可以将多个参数作为数组传递:


@Target({ ElementType.PARAMETER, ElementType.LOCAL_VARIABLE })

配置的下一个重要部分是@Retention注释。

此注释指示我们的注释可用的代码生命周期部分:

保留政策.SOURCE 标有SOURCE保留策略的注释在运行时被丢弃。
保留政策.CLASS 标有CLASS保留策略的注释被写入.class文件,但在运行时被删除。
保留策略.RUNTIME 标有RUNTIME保留策略的注释在运行时持续存在,并且可以在运行时在我们的程序中访问。

还有一些注释可用于配置:

注解 价值
@遗传 指示派生类继承父类的注释实现。
@Documented 这表示注释将包含在生成的 Javadoc 文档中。

现在让我们尝试创建我们自己的注释。

我们将为类和方法创建一个注释,并包含有关代码作者和版本的信息:


    @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
   String author() default "Author";
   String version() default "0.0";
}

我们可以将注释应用于方法和类。我们注释的元数据将在运行时可用。注意注释的参数:我们可以提供两个参数(作者和版本),也可以省略它们。如果我们省略它们,则将使用指定的默认值(默认 "Author"默认 "0.0" )。

值得注意的是,我们不必为参数指定默认值。在这种情况下,该参数成为强制性的。

传递参数时,我们必须使用符号value = "value"指定相应的参数。参数必须始终显式命名,即使注解只有一个参数。

让我们将注解应用于几个类:


@Info
public class MyClass1 {
   @Info
   public void myClassMethod() {}
}
 
@Info(version = "2.0")
public class MyClass2 {
   @Info(author = "Anonymous")
   public void myClassMethod() {}
}
 
@Info(author = "Anonymous", version = "2.0")
public class MyClass3 {
   @Info(author = "Anonymous", version = "4.0")
   public void myClassMethod() {}
}