目的:扫描出Test中添加了注解的方法,并执行它。
首先,我们需要自定义一个最简单的注解类( 没有参数 ),注解名为: CustomTest
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) //该注解运行时保留
@Target(ElementType.METHOD) //该注解应用于方法上
@Documented //该注解可以被文档化
public @interface CustomTest {
//使用@intarface自定义注解时,会自动继承java.lang.annotation.Annotation接口
}
元注解
1. @Documented —— 指明拥有这个注解的元素可以被javadoc此类的工具文档化。
这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。
如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。
2. @Target——指明该类型的注解可以注解的程序元素的范围。
该元注解的取值可以为TYPE,METHOD,CONSTRUCTOR,FIELD等。
如果Target元注解没有出现,那么定义的注解可以应用于程序的任何元素。
3. @Inherited——指明该注解类型被自动继承。
如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,
那么也将自动查询当前类的父类是否存在Inherited元注解,
这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。
4.@Retention——指明了该Annotation被保留的时间长短。
RetentionPolicy取值为SOURCE,CLASS,RUNTIME。
然后,我们需要定义一个Test类,并为Test里的方法添加上我们上一步写好的注解: @CustomTest
public class Test {
@CustomTest
public void Test1(){
System.out.println("i am Test1"); //用于判断方法是否被执行
}
public void Test2(){
System.out.println("i am Test2"); //用于判断方法是否被执行
}
@CustomTest
public void Test3(){
System.out.println("i am Test3"); //用于判断方法是否被执行
}
}
这里我们为 Test1() 与 Test3() 添加了我们自定义的 @CustomTest 注解。
最后,我们定义一个 Helper 类,Helper里放入main方法与我们自定义的扫描方法 scan()
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Helper {
public static void main(String[] args)
throws InstantiationException,
IllegalAccessException, InvocationTargetException
{
scan(Test.class); //调用scan方法,将Test.class传入该方法中
}
public static void scan(Class clazz) throws InvocationTargetException, IllegalAccessException, InstantiationException {
//用类加载机制创建对象,并放在一个Object对象中(Object 是所有类的父类)
Object object = clazz.newInstance();
//获取clazz中的所有方法,并放在一个集合里进行遍历
for(Method method : clazz.getDeclaredMethods()){
//获取方法中的所有注解,并放在一个集合里进行遍历
for(Annotation annotation : method.getAnnotations()) {
//如果注解不为 null
if (annotation != null) {
//执行该方法
method.invoke(object);
}
}
}
}
}
运行Helper类的main方法,执行结果如下:
i am Test1
i am Test3
Test1() 与Test3() 均被添加了注解,所以最后会被执行,而Test2() 没有添加注解,所以不会被执行。