自定义注解
前言
Github:https://github.com/HealerJean
一、元注解
解释:元注解是指注解的注解。有四种元注解类型:
@Retention、@Target、@Document、@Inherited注解方法不能有参数。
注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组。
注解方法可以包含默认值,如果没有默认值,则必须赋值
1、@Retention
- 解释:定义注解的保留策略, 表示注解类型保留时间的长短,它接收
RetentionPolicy参数,可能的值有
| 使用 | 说明 |
|---|---|
@Retention(RetentionPolicy.SOURCE) |
注解仅存在于源码中,在 class 字节码文件中不包含 |
@Retention(RetentionPolicy.CLASS) |
默认的保留策略,注解会在 class 字节码文件中存在,但运行时无法获得 |
@Retention(RetentionPolicy.RUNTIME) |
注解会在 class 字节码文件中存在,在运行时可以通过反射获取到,经常使用 |
2、@Target
-
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
-
注解所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
| 使用 | |
|---|---|
@Target({ElementType.CONSTRUCTOR}) |
构造器 |
@Target({ElementType.FIELD}) |
描述域,字段 |
@Target({ElementType.LOCAL_VARIABLE}) |
局部变量 |
@Target({ElementType.PACKAGE}) |
包 |
@Target({ElementType.PARAMETER}) |
参数 |
@Target({ElementType.TYPE}) |
类、接口(包括注解类型) 或enum声明 |
@Target({ElementType.METHOD}) |
方法 |
3、@Documented
解释:@Documented:用于描述其它类型的 annotation 应该被作为被标注的程序成员的公共 API,因此可以被例如javadoc此类的工具文档化。Documented 是一个标记注解,没有成员。 一般用不到
4、@Inherited
-
解释:表示一个注解类型会被自动继承,只有作用在类上时,会被子类继承此自定义的注解,其余情况都不会继承
- 类继承关系中
@Inherited的作用:- 类继承关系中,子类会继承父类使用的注解中被
@Inherited修饰的注解
- 类继承关系中,子类会继承父类使用的注解中被
- 接口继承关系中
@Inherited的作用:- 接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被
@Inherited修饰
- 接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被
- 类实现接口关系中
@Inherited的作用:类实现接口时不会继承任何接口中定义的注解。
- 类继承关系中
二、使用
1、方法上使用注解
1)自定义注解
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo {
String value() default ""; //如果只有这个注解,则,直接 @MethodInfo("Healerjean");
String author() default "HealerJean";
String date(); //没有默认值,必须给值
int revision() default 1;
String comments();
}
2)实例测试
1、method.isAnnotationPresent 判断method是不是被某个注解注解了
2、method方法中取得所有的注解:for (Annotation anno : method.getDeclaredAnnotations())
3、method中取得某个注解,并获取相应的值,MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
public class AnnotationParsingMain {
public static void main(String[] args) {
try {
for (Method method : AnnotationParsingMain.class
.getClassLoader()
.loadClass(("com.hlj.annotation.AnnotationMain"))
.getMethods()) {
//判断是不是 @MethodInfo的注解
if (method.isAnnotationPresent(com.hlj.annotation.method.MethodInfo.class)) {
try {
for (Annotation anno : method.getDeclaredAnnotations()) {
System.out.println("被注解的方法名字为 " + method + " : " + anno);
}
MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
if (methodAnno.revision() != 1) {
System.out.println("注解中的参数revision 不等于1,: " + method);
}
} catch (Throwable ex) {
ex.printStackTrace();
}
}
}
} catch (SecurityException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}


