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

    Java注解

    内容参考:

    【注解】Annotation Target ElementType

    https://www.cnblogs.com/baiqiantao/p/7469746.html

    在这篇博客里已经将注解解释的相当详细, 在此基础上进行一定的增删.

    加之在 Java编程思想这本书中, 有一章节专门用来介绍注解, 感兴趣的话可以看一下.

    基础

    在java中,注解作为程序的元数据嵌入到程序当中, 元数据标签的存在并不影响程序代码的编译和执行。

    注解可以被一些解析工具或者是编译工具进行解析, 其信息可以在编译、加载和运行时被读取(具体详见元注解 Retention),并执行相应的处理。

    什么是元数据

    元数据(Metadata),又称中介数据、中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能.

    其余地方就不再引用, 如注解的优缺点, 和XML文件的对比. 从这里已经有了基本的核心. 用来描述数据的数据.

    在研究Java注解的具体功用, 特性等, 不如从案例开始;

    public @interface TestAnnotation {
    }
    

    通过这种方式我们就定义了一个注解, @interface. 我们来看一个熟悉的注解:

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Controller {
        String value() default "";
    }
    

    这是Spring中的 @Controller注解, 那我们怎样解读这个注解呢?

    @Controller("test")
    //@Controller(value = "test")
    public class TestController() {
    
    }
    

    使用方法解读

    在编程思想中有一句很有趣的话, 如果没有处理解读注解的工具, 注解也不会比注释来的更有用处.

    在真正解读之前,在这里提出几点关于注解的说明, 注解本身是类似于Java接口的, 但是有几点区别 :

    1. 注解的成员变量以无形参的方法形式来声明, 在这里表示的意思就是, 它是个成员变量, 长得像方法, 因此不要想着各种各样的实现, 其方法名和返回值定义了该成员变量的名字和类型。
    2. 成员变量的类型限定为:基本类型、String、Enums、Annotation(但不能是自身)或者是这些类型的数组, 甚至于返回值也可以是注解.
    3. 使用注解时, 需要为所有的成员变量都进行赋值, 除非使用default关键字设置默认值
    4. 当 成员变量 value 为唯一的需要被赋值的属性值(也就是只有value设置default时), 此时在使用时无需使用键值对的形式.(示例见下文)
    5. 注解可以被用来注解其他注解. 甚至可以注解自身.

    对注解有了这些基本的了解, 继续来看, 如何解读一个注解?在我目前的理解中, 反射.

    //定义注解, 在这里需要指定为RUNTIME, 否则无法通过反射获取到.
    //因为反射特点之一就是 运行时执行.
    @Retention(RetentionPolicy.RUNTIME)
        public @interface TopClass {
            String name();
            String username() default "zzzxxxx";
    }
    
    @TopClass(name = "zzzzzz")
        public class AnnotationTest {
    }
    
    public class ReadAnnotation {
    
        public static void main(String[] args) {
    
            TopClass tp = AnnotationTest.class.getAnnotation(TopClass.class);
    
            System.out.println(tp.name());
            System.out.println(tp.username());
        }
    }
    

    结果输出 zzzzzz; zzzxxxx;

    同时在 Class类中, 还有几种有关注解的处理方式, 就不多介绍了.而 Method, Field等其他类中都实现了对应的方法.

    因此在Spring中指定了扫描的包, 会扫描对应的Class, 找到相应的注解, 创建相应的实例, 这种流程也就不难理解了.

    元注解

    Java为我们提供了4种元注解(元注解专门用来注解其他注解):

    @Target, @Retention, @Documented, @Inherited

    1. 如:

      @Documented
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.ANNOTATION_TYPE)
      public @interface Target {
      ElementType[] value();
      }

    元注解

    1. @Target

      这个注解被用来指定 注解可以用在什么地方.

      其值 ElementType 表示类型:

       public enum ElementType {
           TYPE,           // 类, 接口(包括注解类型)或enum声明 
           FIELD,          // 域声明, 包括enum实例
           LOCAL_VARIABLE, // 局部变量
           METHOD,         // 方法声明
           PACKAGE,        // 包声明
           PARAMETER,      // 参数声明
           CONSTRUCTOR,    // 构造器声明
           ANNOTATION_TYPE,// 作用目标是注解
           TYPE_PARAMETER, // 看了好久都不明白, 这两个1.8注解的具体作用
           TYPE_USE        //
       }
      

      而元注解本身都有 @Target(ElementType.ANNOTATION_TYPE) 所注解.

      而如果不声明, 则可以用于任何地方.但在 Java8以后,如果不声明的话, TYPE_PARAMETER, TYPE_USE 所适合的场景并不能使用 相应注解.

    2. Retention 保留策略

       @Documented
       @Retention(RetentionPolicy.RUNTIME)
       @Target(ElementType.ANNOTATION_TYPE)
       public @interface Retention {
           RetentionPolicy value();
       }
      
       public enum RetentionPolicy {
      
           SOURCE,         //表明注解会被编译器忽略
           CLASS,          //表明注解仅在编译时使用, 在运行时被抛弃.
           RUNTIME         //编译及运行时都会保留相应注解, 反射可用.
       }
      

      默认值为: CLASS; 反射时必须指定为 RUNTIME;

    3. Documented 文档化

    4. Inherited 自动继承

      指明如果父类使用了 被元注解 注解 的 注解, 此注解会被继承. 如果使用注解类型注解类以外的任何事物,此元注解类型都是无效的。还要注意,此元注解仅促成从超类继承注解;对已实现接口的注解无效。

    目前来说就这么多, 依然遗留问题是, 1.8 ElementType中新添加的两个对象.

  • 相关阅读:
    UU跑腿
    Java基础之接口与抽象类的区别
    经典面试题:Redis为什么这么快?
    isBlank与isEmpty
    阅读联机API文档
    从文本中取出链接地址 并检测链接地址能否打开
    2019-01-19=树莓派学习总结
    单片机知识点
    Linux 编程题
    嵌入式基础知识
  • 原文地址:https://www.cnblogs.com/zyzdisciple/p/8760052.html
Copyright © 2011-2022 走看看