比如叫做 MyAnnotation.java
public @interface MyAnnotation {
}
现在我们就有了一个自定义的注解 @MyAnnotation。但是现在这个注解还不能添加在任何地方,需要继续修改。
需要在文件中添加@Target,用来规定@MyAnnotation的作用目标
@Target(ElementType.FIELD)
public @interface MyAnnotation {
}
@Target(ElementType.FIELD)的意思是@MyAnnotation这个注解可以作用在一个class的字段中。
@Target中的参数可以是一个数组,@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}),表示这个注解可以添加在,类,方法,属性上。
ElementType有多种类型,说明如下:
代码 | 说明 |
---|---|
@Target(ElementType.TYPE) | 接口、类、枚举、注解 |
@Target(ElementType.FIELD) | 字段、枚举的常量 |
@Target(ElementType.METHOD) | 方法 |
@Target(ElementType.PARAMETER) | 方法参数 |
@Target(ElementType.CONSTRUCTOR) | 构造函数 |
@Target(ElementType.LOCAL_VARIABLE) | 局部变量 |
@Target(ElementType.ANNOTATION_TYPE) | 注解 |
@Target(ElementType.PACKAGE) | 包 |
这时候我们的注解就可以正常的添加在想要的位置了。但是这时候这个注解是没有任何意义的,我们还需要让我们的程序在运行的时候能够读取到我们的自定义注解,现在我们继续修改。
需要继续添加注解@Retention
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {
}
@Retention(RetentionPolicy.RUNTIME)的意思是在@MyAnnotation的注解会保留在运行时。这样的话这个注解就可以在代码运行的时候通过反射取到了。它有下面的几种取值范围:
代码 | 说明 |
---|---|
@Retention(RetentionPolicy.SOURCE) | 注解仅存在于源码中 |
@Retention(RetentionPolicy.CLASS) | 注解会在class字节码文件中存在 |
@Retention(RetentionPolicy.RUNTIME) | 注解会在class字节码文件中存在,运行时可以通过反射获取到 |
这个时候这个注解就是我们在代码中可以使用的了。想要使子类也能取到 @MyAnnotation 信息的话,需要继续修改。
需要添加注解@Inherited
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}
这个注解只有在@Target(ElementType.TYPE)才可以使用,对其他无效。
例如自定义注解 @MyAnnotation
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}
添加在一个class中
@MyAnnotation
public class OneClass {
}
新建一个TwoClass继承OneClass,并获取子类的注解。
public class TwoClass extends OneClass {
public static void main(String[] args) {
MyAnnotation myAnnotation = TwoClass.class.getAnnotation(MyAnnotation.class);
System.out.println(myAnnotation);
}
}
此时的输出结果是 null
。我们继续修改我们的注解 MyAnnotation
import java.lang.annotation.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}
这是继续运行TwoClass,输出结果为:@com.example.xxx.MyAnnotation()
。
以上就是怎样自定义一个注解。
注解中的属性定义类似interface中的方法。
格式是 返回值 属性名称()。
如果有默认值 格式为 返回值 属性名称() default 你的默认值。
返回值 可以是基本数据类型,枚举类。
例如:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
String value() default "hejiaxuan";
int aint();
long along();
ElementType type() default ElementType.FIELD;
}