注解

作者: 面向星辰大海的程序员 | 来源:发表于2020-04-26 23:09 被阅读0次

    注解的定义
    Java注解用于为Java代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上是用于这一目的的。Java注解是从Java5开始添加到Java的。

    注解即标签
    注解就是为 类,接口,方法,属性等打上一个标签

    如何自定义注解
    1.通过@interface关键字定义

    public @interface Test {
    }
    
    

    元注解:注解的注解,就是标签的标签
    有5种:@Retention、@Document、@Target、@Inherited、@Repeatable
    @Repeatable
    java8新添加的,可重复的意思,被此注解注释的注解可以重复使用在一个对象

    @Retention
    Retention的英文意思是保留期的意思。当@Retention应用到一个注解上的时候,它解释说明了这个注解的存活时间。
    取值如下:
    1.RetentionPolicy.SOURCR:注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视
    2.RetentionPolicy.CLASS:注解只被保留到编译进行的时候,它并不会被加载到JVM中。
    3.RetentionPolicy.RUNTIME:注解可以保留到程序运行的时候,他会保留到JVM中,所以在运行程序时可以获取到它们。

    @Target
    Target是目标的意思、@Target指定了注解运用的地方
    当一个注解被@Target注解时,这个注解就被限定了运用场景。
    举例:原本标签可以任意贴在认任何地方,但是被@Target注释的标签只能贴在指定范围内,比如类、方法、属性等。
    取值如下:
    /** 类、接口(包括注释类型)或enum声明 /
    TYPE,
    /
    字段声明(包括enum常量) /
    FIELD,
    /
    方法声明 /
    METHOD,
    /
    * 正式的参数声明,方法的参数进行注解/
    PARAMETER,
    /
    * 构造函数声明 /
    CONSTRUCTOR,
    /
    局部变量声明 /
    LOCAL_VARIABLE,
    /
    注释类型声明 /
    ANNOTATION_TYPE,
    /
    * 包声明/
    PACKAGE,
    /
    *
    * 类型参数声明
    * @since 1.8
    /
    TYPE_PARAMETER,
    /
    *
    *使用类型
    * @since 1.8
    */
    TYPE_USE

    @Document
    顾名思义,这个元注解肯定和文档有关,他的作用是能将注解的元素包含到Javadoc中去。ElementType.TYPE可以给一个类型进行注解,比如类、接口、枚举
    @Inherited
    Inherited是继承的意思,但是并不是说注解本身可以继承,而是说如果一个超类被@Inherited注解过的注解进行注解的话,那么如果它的子类没有被任何注解注释的话,那么这个子类就继承了超类的注解。

    注解的属性
    注解的属性也叫做成员变量。注解只有成员变量,没有方法。
    在注解中定义属性时它的类型必须是8种基本数据类型外加类(Class)、接口、注解以及他们的数组,注解种的属性可任意有默认值,默认值需要用default 关键字指定

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Test{
    int id() default -1;
    String msg() default "Hello";
    }
    

    注解的提取
    运行期注解通过反射获取。首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解

    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
    

    然后通过 getAnnotation() 方法来获取 Annotation 对象。

     public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
    

    或者是 getAnnotations() 方法。

    public Annotation[] getAnnotations() {}
    

    前一种方法返回指定类型的注解,后一种方法返回注解到这个元素上的所有注解。
    如果获取到的 Annotation 如果不为 null,则就可以调用它们的属性方法了。比如

    @Test()
    public class TestDemo{  
    public static void main(String[] args) {
        boolean hasAnnotation =                 TestDemo.class.isAnnotationPresent(Test.class);
            if ( hasAnnotation ) {
                TestAnnotation testAnnotation =     TestDemo.class.getAnnotation(Test.class);
                System.out.println("id:"+testAnnotation.id());
                System.out.println("msg:"+testAnnotation.msg());
            }
        }
    }   
    

    APT

    注解的用处:
    1.提供信息给编译器:编译器可以利用注解来探测错误和警告信息。(AS)
    2.编译阶段时的处理:软件工具可以利用注解信息来生成代码、Html、文档或者做其他相应处理。(aapt2)
    3.运行时的处理:某些注解可以在程序运行的时候接受代码的提取。(通过反射,应该有个工具在运行期间获取注解信息)

    3个知识点:Java注解、java反射、依赖注入

    依赖注入标准

    @Inject

    注解 @Inject
    标识了可注入的构造器、方法或字段。可以用于静态或实例成员。一个可注入的成员可以被任何访问修饰符(private、package-private、protected、public)修饰。注入顺序为构造器,字段,最后是方法。超类的字段、方法将优先于子类的字段、方法被注入。对于
    同一个类的字段是不区分注入顺序的,同一个类的方法亦同

    Provider<T>

    接口 Provider 用于提供类型 T 的实列。Provider 是一般情况是由注入器实现的。对于任何可注入的 T 而言,您也可以注入 Provider<T>。与直接注入 T 相比,注入 Provider<T> 使得:

    • 可以返回多个实例。
    • 实例的返回可以延迟化或可选
    • 打破循环依赖。
    • 可以在一个已知作用域的实例内查询一个更小作用域内的实例。
        class Car {
           @Inject Car(Provider<Seat> seatProvider) {
                Seat driver = seatProvider.get();
                Seat passenger = seatProvider.get();
               …
        }
    }
    
    • get()
      用于提供一个完全构造的类型 T 的实例。
      异常抛出:RuntimeException —— 当注入器在提供实例时遇到错误将抛出此异常。例如,对于一个可注入的成员 T
      抛出了一个异常,注入器将包装此异常并将它抛给 get()
      的调用者。调用者不应该尝试处理此类异常,因为不同注入器实现的行为不一样,即使是同一个注入器,也会因为配置不同而表现的行为不同。

    @Qualifier

    用于标识限定器注解。任何人都可以定义新的限定器注解。一个限定器注解:

    • 是被 @Qualifier、@Retention(RUNTIME) 标注的,通常也被 @Documented 标注。
    • 可以拥有属性。
    • 可能是公共 API 的一部分,就像依赖类型一样,而不像类型实现那样不作为公共 API 的一部分。
    • 如果标注了 @Target 可能会有一些用法限制。本规范只是指定了限定器注解可以被使用在字段和参数上,但一些注入器配置可能使用限定器注解在其他一些地方(例如方法或类)上。

    @Named

    • 基于 String 的[限定器]

    @Scope

    • 用于标识作用域注解。一个作用域注解是被标识在包含一个可注入构造器的类上的,用于控制该类型的实例如何被注入器重用。缺省情况下,如果没有标识作用域注解,注入器将为每一次注入都创建(通过注入类型的构造器)新实例,并不重用已有实例。如果多个线程都能够访问一个作用域内的实例,该实例实现应该是线程安全的。作用域实现由注入器完成。

    @Singleton

    • 标识了注入器只实例化一次的类型。该注解不能被继承

    相关文章

      网友评论

          本文标题:注解

          本文链接:https://www.haomeiwen.com/subject/rtodwhtx.html