Appearance
Define annotations
Java language uses @interface
syntax to define annotations ( Annotation
). Its format is as follows:
java
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
Annotated parameters are similar to parameterless methods, and you can use default
to set a default value (strongly recommended). The most commonly used parameters should be named value
.
meta-annotation
Some annotations can modify other annotations, and these annotations are called meta annotations. The Java standard library has defined some meta-annotations. We only need to use meta-annotations and usually do not need to write meta-annotations ourselves.
@Target
The most commonly used meta-annotation is @Target
. Use @Target
to define where Annotation
can be applied to the source code:
- Class or interface:
ElementType.TYPE
; - Field:
ElementType.FIELD
; - Method:
ElementType.METHOD
; - Constructor:
ElementType.CONSTRUCTO
R ; - Method parameters:
ElementType.PARAMETER
.
For example, to define that the annotation @Report
can be used on a method, we must add a @Target(ElementType.METHOD)
:
java
@Target(ElementType.METHOD)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
The definition annotation @Report
can be used on methods or fields, and the @Target
annotation parameters can be turned into arrays { ElementType.METHOD, ElementType.FIELD }
:
java
@Target({
ElementType.METHOD,
ElementType.FIELD
})
public @interface Report {
...
}
In fact, value
defined by @Target
is ElementType[]
array. When there is only one element, the array writing method can be omitted.
@Retention
Another important meta-annotation @Retention
defines the life cycle of Annotation
:
- Compile time only:
RetentionPolicy.SOURCE
; - Only class files:
RetentionPolicy.CLASS
; - Runtime:
RetentionPolicy.RUNTIME
.
If @Retention
does not exist, the Annotation
defaults to CLASS
. Because usually our custom Annotation
is RUNTIME
, so be sure to add @Retention(RetentionPolicy.RUNTIME)
This meta-annotation:
java
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
@Repeatable
Use the @Repeatable
meta-annotation to define whether Annotation
is repeatable. This annotation is not particularly widely used.
java
@Repeatable(Reports.class)
@Target(ElementType.TYPE)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
@Target(ElementType.TYPE)
public @interface Reports {
Report[] value();
}
After being modified @Repeatable
, you can add multiple @Report
annotations at a certain type declaration:
java
@Report(type=1, level="debug")
@Report(type=2, level="warning")
public class Hello {
}
@Inherited
Use @Inherited
to define whether a subclass can inherit Annotation
defined by the parent class. @Inherited
is only valid for @Target(ElementType.TYPE)
type annotation
, and only for class
inheritance, and is invalid for interface
inheritance:
java
@Inherited
@Target(ElementType.TYPE)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
When using, if a class uses @Report
:
java
@Report(type=1)
public class Person {
}
Then its subclasses also define this annotation by default:
java
public class Student extends Person {
}
How to define annotation
Let’s summarize the steps to define Annotation
:
The first step is to define the annotation with @interface
:
java
public @interface Report {
}
The second step is to add parameters and default values:
java
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
Define the most commonly used parameters as value()
, and it is recommended that all parameters be set to default values.
The third step is to configure the annotation using meta-annotations:
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
Among them, @Target
and @Retention
must be set, and @Retention
is generally set to RUNTIME
, because our custom annotations usually require reading during runtime. Under normal circumstances, there is no need to write @Inherited
and @Repeatable
.
Summary
Java uses @interface
to define annotations;
Multiple parameters and default values can be defined, and core parameters use value
names;
@Target
must be set to specify the scope to Annotation
can be applied;
should be set @Retention(RetentionPolicy.RUNTIME)
It is convenient to read the Annotation
during runtime.