美文网首页
Annotation注解

Annotation注解

作者: 码而优则仕 | 来源:发表于2020-06-23 23:27 被阅读0次

    Annotation注解

    上节介绍的反射似乎很厉害,可以在运行时操作和修改对象的行为,但是要使用反射,最起码要知道待反射的类所在的包路径和类名。所以项目中我们必须记录哪些类是需要反射进行获取的。

    标记类信息的方式有如下几种:

    1. XML方式保存类相关信息:

      <bean id="welcomeService" class="cn.com.yuns.service.impl.WelcomeServiceImpl"/>
      
    2. 用注解来保存类相关信息

      @Service
      public class JybWechatService implements IJybWechatService {
      

    注解

    提供一种为程序元素设置元数据的方法,什么是所谓的元数据?就是数据的数据即对数据的一种描述

    • 元数据是添加到程序元素如方法,字段,类和包上的额外信息。
    • 注解是一种分散式的元数据设置方式,XML是集中式的设置方式
    • 注解不能直接干扰程序代码的运行。

    总的来说:注解就是将我们需要的数据存储起来,在以后的某一时刻去使用,可能是编译时也可能是运行时。

    所有注解均继承自Annotation这个接口。

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface TestAnnotation {
    }
    

    但是我们看注解里面没有体现继承自Annotation这个接口,怎样才能看到呢?

    首先需要执行 javac com/yuns/demo/annotation/TestAnnotation.java 命令将.java文件编译为.class文件,然后使用命令

    javap -verbose com/yuns/demo/annotation/TestAnnotation 命令将.class文件反编译出来,我们可以看见反编译出来的类信息中就有接口继承自Annotation的信息:

    Classfile /Users/wsq/Documents/demo/simpleframework/src/main/java/com/yuns/demo/annotation/TestAnnotation.class
      Last modified 2020-6-23; size 405 bytes
      MD5 checksum b830500c3cccd0ce2cbaaba7c81d3196
      Compiled from "TestAnnotation.java"
    public interface com.yuns.demo.annotation.TestAnnotation extends java.lang.annotation.Annotation
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
    Constant pool:
       #1 = Class              #14            // com/yuns/demo/annotation/TestAnnotation
       #2 = Class              #15            // java/lang/Object
       #3 = Class              #16            // java/lang/annotation/Annotation
       #4 = Utf8               SourceFile
       #5 = Utf8               TestAnnotation.java
       #6 = Utf8               RuntimeVisibleAnnotations
       #7 = Utf8               Ljava/lang/annotation/Target;
       #8 = Utf8               value
       #9 = Utf8               Ljava/lang/annotation/ElementType;
      #10 = Utf8               METHOD
      #11 = Utf8               Ljava/lang/annotation/Retention;
      #12 = Utf8               Ljava/lang/annotation/RetentionPolicy;
      #13 = Utf8               SOURCE
      #14 = Utf8               com/yuns/demo/annotation/TestAnnotation
      #15 = Utf8               java/lang/Object
      #16 = Utf8               java/lang/annotation/Annotation
    {
    }
    SourceFile: "TestAnnotation.java"
    RuntimeVisibleAnnotations:
      0: #7(#8=[e#9.#10])
      1: #11(#8=e#12.#13)
    
    

    注解的功能:

    • 作为特定的标记,告诉编译器一些信息 帮助编译器做一些语法检查 如:@Override,
    • 程序编译时动态处理,如动态生成代码:如@data
    • 程序运行时动态处理,作为额外信息的载体,如获取注解信息,(这个是重点),获取注解后获取各种信息

    简单来说注解只是一种特殊的注释,如果没有解析它的代码,它可能连注释都不如。

    注解的分类

    1. 标准注解:Override(重写),Deprecated(表示不再维护,有风险,不鼓励使用),SuppressWarnings(表示需要忽略某项Warning)
    2. 元注解(注解的注解):@Retention,@Target,@Inherited,@Documented
    3. 自定义注解:根据业务需要定义的注解(定义和元注解息息相关,自定义注解是使用元注解来定义的)

    元注解

    用于修饰注解的注解,通常用在注解的定义上;

    Java中的元注解

    1. @Target :指定注解的作用,目标

      被描述的注解可以被用在什么地方:

      packages,types(类,接口,枚举,Annotation类型)

      类型成员(方法,构造方法,成员变量,枚举值)

      方法参数和本地变量(循环变量,catch参数)

      public enum ElementType {
          /**类级别 Class, interface (including annotation type), or enum declaration */
          TYPE,
      
          /** 成员变量Field declaration (includes enum constants) */
          FIELD,
      
          /** 方法级别 Method declaration */
          METHOD,
      
          /** 方法参数 Formal parameter declaration */
          PARAMETER,
      
          /** 构造器 Constructor declaration */
          CONSTRUCTOR,
      
          /** 本地变量 Local variable declaration */
          LOCAL_VARIABLE,
      
          /** 注解标签 Annotation type declaration */
          ANNOTATION_TYPE,
      
          /** 包 Package declaration */
          PACKAGE,
      
          /**
           * Type parameter declaration
           *
           * 标注类型参数,作用在泛型类的实参 @since 1.8
           */
          TYPE_PARAMETER,
      
          /**
           * Use of a type 可以使用在所有地方
           *
           * @since 1.8
           */
          TYPE_USE
      }
      

      TYPE:

      @Target({ElementType.TYPE})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      @Component
      public @interface Controller {
      

      FIELD

      @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      public @interface Autowired {
      

      METHOD

      @Target(ElementType.METHOD)
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      @RequestMapping(method = RequestMethod.DELETE)
      public @interface DeleteMapping {
      

    PARAMETER

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequestBody {
    
    1. @Retention:指定注解的生命周期

      没描述的注解在什么范围内有效

    public enum RetentionPolicy {
        /**
         * Annotations are to be discarded by the compiler.
         * 被描述的注解在原文件中保留,但是在编译后的class文件中去除
         */
        SOURCE,
    
        /**
         * Annotations are to be recorded in the class file by the compiler
         * but need not be retained by the VM at run time.  This is the default
         * behavior.不仅出现在原文件中,页也出现在class文件中
         */
        CLASS,
    
        /**
         * Annotations are to be recorded in the class file by the compiler and
         * retained by the VM at run time, so they may be read reflectively.
         * 该类在运行时获得该注解的信息,运行时保留注解信息
         * @see java.lang.reflect.AnnotatedElement
         */
        RUNTIME
    }
    

    SOURCE

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface TestAnnotation {
    }
    
    public class HpMouse implements Mouse {
        @Override
        @TestAnnotation
        public void sayHi() {
            System.out.println("我是惠普鼠标");
        }
    }
    
    javac com/yuns/demo/pattern/factory/entity/HpMouse.java  编译后:
    
    package com.yuns.demo.pattern.factory.entity;
    
    public class HpMouse implements Mouse {
        public HpMouse() {
        }
        public void sayHi() {
            System.out.println("我是惠普鼠标");
        }
    }
    

    CLASS

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.CLASS)
    public @interface TestAnnotation {
    }
    
    public class HpMouse implements Mouse {
        @Override
        @TestAnnotation
        public void sayHi() {
            System.out.println("我是惠普鼠标");
        }
    }
    

    javac com/yuns/demo/pattern/factory/entity/HpMouse.java 编译后:

    public class HpMouse implements Mouse {
        public HpMouse() {
        }
        @TestAnnotation
        public void sayHi() {
            System.out.println("我是惠普鼠标");
        }
    }
    

    RUNTIME

    该类在运行时获得该注解的信息,运行时保留注解信息,程序可以在运行时通过反射来获取注解的信息

    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Autowired {
    
    1. @Documented:指定直接是否应当被包含在JavaDoc文档中

      加这个注解的注解会在生成的JavaDoc文档中出现注解

    2. @Inherited:是否允许子类继承该注解

      具有可继承性,注解修饰某个类,则该类的自类可以继承这个注解

    相关文章

      网友评论

          本文标题:Annotation注解

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