注解

目录

 

一、自定义注解

二、元注解

三、解析注解


一、自定义注解

自定义注解格式:

//@interface 注解名
@interface MyTest{
    /**
     * 注解属性
     * 属性适用的数据类型:
     * int,short,long,double,byte,char,boolean,float,String,Class
     * 以上类型的数组形式都支持
     *
     * */
    
    //注解可以有属性,属性名必须带()
    String name() default "test";
    int[] ids();
}

注解使用:

public class Test {
    @MyTest(ids = {1,2})
    public void method1(){
    }
}

二、元注解

元注解使用:

/***
 *      元注解是sun公司提供的。
 *      元注解是用在自定义注解上的注解。
 *      元注解是用来注解自定义注解的。
 *
 *      元注解有两个:
 *          @Target:约束自定义注解只能在哪些地方使用,
 *              -- 但是默认的注解可以在类,方法,构造器,成员变量,... 使用。
 *
 *          @Retention:申明注解的生命周期
 *              -- 申明注解的作用范围:编译时,运行时。
 *
 *      @Target
 *           * 作用:用来标识注解使用的位置,如果没有使用该注解标识,则自定义的注解可以使用在任意位置。
 *           * 可使用的值定义在ElementType枚举类中,常用值如下
 *              TYPE,类,接口
 *              FIELD, 成员变量
 *              METHOD, 成员方法
 *              PARAMETER, 方法参数
 *              CONSTRUCTOR, 构造器
 *              LOCAL_VARIABLE, 局部变量
 *
 *      @Retention
 *          作用:用来标识注解的生命周期(有效存活范围)
 *           * 可使用的值定义在RetentionPolicy枚举类中,常用值如下
 *           * SOURCE: 注解只作用在源码阶段,生成的字节码文件中不存在
 *           * CLASS:  注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值.
 *           * RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)
 *      小结:
 *         @Target约束自定义注解可以标记的范围。
 *         @Retention用来约束自定义注解的存活范围。
 */
@Target({ElementType.TYPE,ElementType.METHOD}) //只在类和方法上使用
@Retention(RetentionPolicy.RUNTIME) //一直存活
@interface MyTest{
}

三、解析注解

模拟实现Junit注解

/***
 *      我们会使用注解注释一个类的成分,那么就设计到要解析出这些注解的数据。
 *      开发中经常要知道一个类的成分上面到底有哪些注解,注解有哪些属性数据,这都需要进行注解的解析。
 *
 *      与注解解析相关的接口
 *           1. Annotation: 注解类型,该类是所有注解的父类。注解都是一个Annotation的对象
 *           2. AnnotatedElement:该接口定义了与注解解析相关的解析方法
 *             所有的类成分Class, Method , Field , Constructor:都实现了AnnotatedElement接口
 *             他们都拥有解析注解的能力:
 *                  a.Annotation[]	getDeclaredAnnotations()
 *                     获得当前对象上使用的所有注解,返回注解数组。
 *                  b.T getDeclaredAnnotation(Class<T> annotationClass)
 *                      根据注解类型获得对应注解对象
 *                  c.boolean isAnnotationPresent(Class<Annotation> annotationClass)
 *                     判断当前对象是否使用了指定的注解,如果使用了则返回true,否则false
 *
 *      解析注解数据的原理
 *          * 注解在哪个成分上,我们就先拿哪个成分对象。
 *          * 比如注解作用成员方法,则要获得该成员方法对应的Method对象,再来拿上面的注解
 *          * 比如注解作用在类上,则要该类的Class对象,再来拿上面的注解
 *          * 比如注解作用在成员变量上,则要获得该成员变量对应的Field对象,再来拿上面的注解
 */

/*******自定义一个注解*******/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyTest{
}

public class Test{

    @MyTest
    public void test1(){
        System.out.println("=====test1=====");
    }

    public void test2(){
        System.out.println("====test2====");
    }

    //用main方法入口代替IDEA菜单执行按钮
    public static void main(String[] args) throws Exception {
        //创建一个实例对象
        Test test = new Test();
        //得到字节码class对象
        Class clazz = Test.class;
        //通过反射获取该类的所有方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            //判断当前Method是否使用了指定的注解
            if(method.isAnnotationPresent(MyTest.class)){
                method.invoke(test);
            }
        }
    }
}

执行main方法只有加了@MyTest注解的方法调用了

执行输出结果:

”=====test1====="

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值