Java高级-注解

注解(Annotation)

  • 注解就是Java代码中的特殊标记,比如:@Override、@Test等,作用是:让其他程序员根据注解信息来决定怎么执行该程序。
  • 注意:注解可以用在类上、构造器上、方法上、成员变量上、参数上、等位置。

自己定义注解

  • 特殊属性名:value

  • 如果注解中只有一个value属性,value名称可以不写

注解的原理

  • 注解本质是一个接口,该接口继承了Annotation接口
  • 使用@注解名(....):其实就是一个实现类对象,实现了该注解以及Annotation接口。

元注解

  • 修饰注解的注解称为元注解
  • @Target

    • 作用:声明被修饰的注解只能在哪些位置使用
    • @Target(ElementType.TYPE,ElementType.FIELD)
      1.Type,类,接口
      2.FIELD,成员变量
      3.METHOD,成员方法
      4.PARAMETER,方法参数
      5.CONSTRUCTOR,构造器
      6.LOCAL_VARIABLE,局部变量
  • @Retention

    • 作用:声明注解的保留周期
    • @Retention(RetentionPolicy.RUNTIME)
      1.SOURCE,只作用在源码阶段,字节码文件中不存在
      2.CLASS(默认值),保留到字节码文件阶段,运行阶段存在
      3.RUNTIME(开发常用),一直保留到运行阶段

注解的解析

  • 什么是注解解析

  • 判断类上、方法上、成员变量上是否存在注解,并把注解里面的内容解析出来
  • 如何解析注解

  • 核心思想:要解析谁上面的注解,就应该先拿到谁。
    • 比如:要解析类上面的注解,则应该先获取该类的Class对象,在通过Class对象解析其上面的注解
    • 比如:要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析其上面的注解。
    • Class、Method、Field、Constructor都实现了AnnotatedElement接口,他们都拥有解析注解的能力
      • AnnotatedElement接口提供解析注解的方法说明
        public Annotation[ ] getDeclaredAnnotations()获取当前对象上面的注解
        public T getDeclaredAnnotation(Class <T> annotationClass)获取指定注解对象
        public boolean isAnnotationPresent(Class <Annotation> annotationClass)判断当前对象是否存在某个注解

案例

  • 解析注解的案例,具体要求如下
    • 1.定义注解MyTest4,要求如下
      • 包含属性:String value()
      • 包含属性:double aaa(),默认值为100
      • 包含属性:String [ ] bbb()
      • 限制注解的使用位置:类和成员变量方法上
      • 指定注解的有效范围:一直到运行时
        • package com.example.Anno;
          
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          
          @Target({ElementType.TYPE, ElementType.METHOD})
          @Retention(RetentionPolicy.RUNTIME)
          public @interface MyTest4 {
              String value();
          
              double aaa() default 100;
          
              String[] bbb();
          
          }
          
    • 2.定义一个类叫:Demo,在类中定义一个test1方法,并在该类和其方法上使用MyTest4注解
      • package com.example.Test;
        
        import com.example.Anno.MyTest4;
        
        @MyTest4(value = "蜘蛛精", bbb = {"至尊宝", "紫霞仙子"}, aaa = 99.5)
        public class Demo {
            @MyTest4(value = "蜘蛛精1", bbb = {"至尊宝1", "紫霞仙子1"}, aaa = 199.5)
        
            public void test1() {
        
            }
        }
        
    • 3.定义一个TestAnnotation测试类,解析Demo类中全部注解
      • package com.example.Test;
        
        import com.example.Anno.MyTest4;
        import org.junit.Test;
        
        import java.lang.annotation.Annotation;
        import java.lang.reflect.Method;
        
        public class TestAnnotation {
            @Test
        
            public void parseClass() {
                // 1.先得到Class对象
                Class c = Demo.class;
                // 2.解析类上的注解
                // 判断该类上是否包含某个注解
                if (c.isAnnotationPresent(MyTest4.class)) {
                    MyTest4 myTest4 = (MyTest4) c.getDeclaredAnnotation(MyTest4.class);
                    System.out.println(myTest4.value());
                    System.out.println(myTest4.aaa());
                    System.out.println(myTest4.bbb());
                }
            }
        
            @Test
            public void parseMethod() throws NoSuchMethodException {
                // 1.先得到Class对象
                Class c = Demo.class;
                Method method = c.getDeclaredMethod("test1");
                // 2.解析方法上的注解
                // 判断该方法上是否包含某个注解
                if (method.isAnnotationPresent(MyTest4.class)) {
                    MyTest4 myTest4 = method.getDeclaredAnnotation(MyTest4.class);
                    System.out.println(myTest4.value());
                    System.out.println(myTest4.aaa());
                    System.out.println(myTest4.bbb().toString());
                }
            }
        
        }
        

注解的应用场景

  • 配合反射等技术来构建框架
  • 案例

    • 定义若干个方法,只要加了MyTest注解,就会触发该方法执行
  • 分析
    • 1.定义一个自定义的注解MyTest,只能注解方法,存活范围是一直都在
      • package com.example.Anno;
        
        import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;
        
        // todo 自定义注解
        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.RUNTIME)
        public @interface MyTest {
        
        }
        
    • 2.定义若干个方法,部分方法加上@MyTest注解修饰,部分方法不加
    • 3.模拟一个Junit程序,可以触发加了@MyTest注解的方法执行
      • package com.example.Test;
        
        
        import com.example.Anno.MyTest;
        
        import java.lang.reflect.InvocationTargetException;
        import java.lang.reflect.Method;
        
        public class TestAnnotation {
            @MyTest
            public void test1() {
                System.out.println("test1---");
            }
        
            public void test2() {
                System.out.println("test2---");
            }
        
            public void test3() {
                System.out.println("test2---");
            }
        
            public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
                TestAnnotation testAnnotation = new TestAnnotation();
                // 启动程序
                // 1.得到Class对象
                Class c = TestAnnotation.class;
                // 2.提取类中的全部方法
                Method[] declaredMethods = c.getDeclaredMethods();
                // 3.遍历数组中的每个方法,然后查看方法是否含有@MyTest注解
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.isAnnotationPresent(MyTest.class)) {
                        declaredMethod.invoke(testAnnotation);
                    }
                }
            }
        }
        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值