zoukankan      html  css  js  c++  java
  • Java-注解

    Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。

    Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。

    以前,『XML』是各大框架的青睐者,它以松耦合的方式完成了框架中几乎所有的配置,但是随着项目越来越庞大,『XML』的内容也越来越复杂,维护成本变高。

    于是就有人提出来一种标记式高耦合的配置方式,『注解』。方法上可以进行注解,类上也可以注解,字段属性上也可以注解,反正几乎需要配置的地方都可以进行注解。

    关于『注解』和『XML』两种不同的配置模式,争论了好多年了,各有各的优劣,注解可以提供更大的便捷性,易于维护修改,但耦合度高,而 XML 相对于注解则是相反的。

    追求低耦合就要抛弃高效率,追求效率必然会遇到耦合。

    内置注解

    Java 定义了一套注解,共有 7 个,3 个在java.lang中,剩下 4 个在 java.lang.annotation 中。

    1. 作用在代码的注解是
    • @Override - 只能标注方法,检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
    • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
    • @SuppressWarnings - 压制警告,@SuppressWarnings(value={"all"})
    1. 作用在其他注解的注解(或者说 元注解)是:
    • @Retention - 只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
    • @Documented - 标记这些注解是否包含在用户文档中。
    • @Target - 只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。
    • @Inherited - 只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。也就是A继承B同时也继承了标注@Inherited的注解
    1. 从 Java 7 开始,额外添加了 3 个注解:
    • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
    • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
    • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

    Annotation 架构

    image-20201221201956275

    1 个 Annotation 和 1 个 RetentionPolicy 关联。

    1 个 Annotation 和 1~n 个 ElementType 关联。

    Annotation.java

    package java.lang.annotation;
    public interface Annotation {
    
        boolean equals(Object obj);
    
        int hashCode();
    
        String toString();
    
        Class<? extends Annotation> annotationType();
    }
    

    ElementType.java

    package java.lang.annotation;
    
    public enum ElementType {
        TYPE,               /* 类、接口(包括注释类型)或枚举声明  */
    
        FIELD,              /* 字段声明(包括枚举常量)  */
    
        METHOD,             /* 方法声明  */
    
        PARAMETER,          /* 参数声明  */
    
        CONSTRUCTOR,        /* 构造方法声明  */
    
        LOCAL_VARIABLE,     /* 局部变量声明  */
    
        ANNOTATION_TYPE,    /* 注释类型声明  */
    
        PACKAGE             /* 包声明  */
    }
    

    RetentionPolicy.java

    package java.lang.annotation;
    public enum RetentionPolicy {
        SOURCE,            /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了  */
    
        CLASS,             /* 编译器将Annotation存储于类对应的.class文件中。默认行为  */
    
        RUNTIME            /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
    }
    
    1. Annotation 就是个接口。

    2. ElementType 是 Enum 枚举类型,它用来指定 Annotation 的类型,描述注解可以作用在哪些地方,可以对应多个。

    3. RetentionPolicy 是 Enum 枚举类型,它用来指定 Annotation 的策略。就是指定注解的存活时间。

    注解的本质就是一个接口。

    public interface Annotation1 extends Annotation{
        
    }
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    	
    }
    

    @interface意味着它实现了 java.lang.annotation.Annotation接口,即该注解就是一个Annotation

    定义 Annotation 时,@interface 是必须的。

    注意:它和我们通常的 implemented 实现接口的方法不同。Annotation 接口的实现细节都由编译器完成。通过 @interface 定义注解后,该注解不能继承其他的注解或接口。

    其实大部分内置注解我们都很熟悉了,这里不详细列举注解的使用了。

    注解与反射

    拟机规范定义了一系列和注解相关的属性表,也就是说,无论是字段、方法或是类本身,如果被注解修饰了,就可以被写进字节码文件。属性表有以下几种:

    • RuntimeVisibleAnnotations:运行时可见的注解
    • RuntimeInVisibleAnnotations:运行时不可见的注解
    • RuntimeVisibleParameterAnnotations:运行时可见的方法参数注解
    • RuntimeInVisibleParameterAnnotations:运行时不可见的方法参数注解
    • AnnotationDefault:注解类元素的默认值

    对于一个类或者接口来说,Class 类中提供了以下一些方法用于反射注解。

    • getAnnotation:返回指定的注解
    • isAnnotationPresent:判定当前元素是否被指定注解修饰
    • getAnnotations:返回所有的注解
    • getDeclaredAnnotation:返回本元素的指定注解
    • getDeclaredAnnotations:返回本元素的所有注解,不包含父类继承而来的

    方法、字段中相关反射注解的方法基本是类似的,这里不再赘述。

  • 相关阅读:
    ida动态调试--反反调试
    python读取配置文件
    问题解决:局域网内,为啥别人ping不到我的IP
    完全卸载MySQL
    JDK环境配置
    win10无法运行Vmware,怎么办
    查看ie版本
    公开的免费WebService接口分享,用于做接口练习
    SVN更改地址
    Loadrunner录制步骤及说明
  • 原文地址:https://www.cnblogs.com/fuao2000/p/14169874.html
Copyright © 2011-2022 走看看