@Retention@Target
@Target是内置的注解,用于标注当前注解可以被应用的位置.
参数使用ElementType指定,当需要被多个地方使用时可以以数组形式呈现.
如果不指定Target注解,则当前注解可以被应用在任意注解可以使用的位置.
@Retention表示保留级别.
有三个级别:
RetentionPolicy.SOURCE 注解仅保留在源代码中
RetentionPolicy.CLASS(默认值) 注解保留在字节码中,但是反射机制不可访问
RetentionPolicy.RUNTIME 注解保留在字节码中,反射机制可访问
@Target({ElementType.TYPE,ElementType.FIELD})//注解可以被应用在类上和属性上
@Target(ElementType.TYPE)//注解仅能被用在类上
注解上可以定义参数
格式:
类型 参数名() [default 默认值]
注:[]中的内容可以写也可以不写.
default用于指定该参数的默认值,指定后,在使用注解时如果不为该参数赋值时则
采用默认值.例如:
当我们在@AutoRunMethod上定义一个参数:
int value() default 1;
使用时:
@AutoRunMethod(5): value的值为5
@AutoRunMethod(3): value的值为3
@AutoRunMethod: value的值使用默认值1
但是如果没有指定default,那么使用注解时必须为该参数传值.
使用注解时,语法要求传递参数时的格式为:
@注解(参数名1=参数值1[,参数名2=参数值2,....])
如果一个注解中只有一个参数时,参数名建议选取"value".因为使用时可以不指定
该参数的名字.
@AutoRunMethod(1) 由于参数名为value,所以可以这样写.
如果参数名不叫value,例如:
int num();
那么使用时要如下:
@AutoRunMethod(num=1) 此时参数num的值为1.
表示是否被括号内的注解标注过
返回值是boolean值
Class cls=Class.forName("reflect.Person");
boolean mark=cls.isAnnotationPresent(AutoRunClass.class);/
获取一个注解的参数
获取注解上的参数分为2步:
1:获取该方法上的注解AutoRunMethod
2:在通过注解对象获取参数信息
1获取该方法上的@AutoRunMethod这个注解
AutoRunMethod arm = method.getAnnotation(AutoRunMethod.class);
2通过该注解对象获取参数
int d = arm.value();
小练习
自动调用与Test5在同一个包中那些被@AutoRunClass标注的类中被@AutoRunMethod
标注的方法指定次.
次数由@AutoRunMethod参数决定
public class Test5 {
public static void main(String[] args) throws Exception {
File dir = new File(
Test4.class.getResource(".").toURI()
);
//获取该目录中所有的.class文件
File[] subs = dir.listFiles(f->f.getName().endsWith(".class"));
for(File sub : subs) {
String fileName = sub.getName();
//根据.class文件名获取类名 例如:Person.class
String className = fileName.substring(0, fileName.indexOf("."));
//加载类对象
Class cls = Class.forName(
Test4.class.getPackage().getName() + "." + className
);
if(cls.isAnnotationPresent(AutoRunClass.class)){
System.out.println("正在实例化:"+cls.getName());
Object obj = cls.newInstance();
System.out.println(obj);
//获取所有方法
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods){
if(method.isAnnotationPresent(AutoRunMethod.class)){
if(method.isAnnotationPresent(AutoRunMethod.class)){
/*
获取注解上的参数分为2步:
1:获取该方法上的注解AutoRunMethod
2:在通过注解对象获取参数信息
*/
//1获取该方法上的@AutoRunMethod这个注解
AutoRunMethod arm = method.getAnnotation(AutoRunMethod.class);
//2通过该注解对象获取参数
int d = arm.value();
System.out.println("参数:"+d);
System.out.println("自动调用:"+method.getName()+"()");
for (int i=0;i<d;i++){
method.invoke(obj);
}
}
}
}
}
}
}
}