注解在反射机制中的应用

@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);
                            }

                        }

                    }
                }

            }
        }
    }  

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值