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

    框架的底层都是注解和反射。

    1、什么是注解

    英文:Annotation

    官方:java注解用于为java代码提供元数据。

    注解像类和接口一样新建,如建立一个叫ThisIsAnnotation的注解。

    public @interface ThisIsAnnotation {
          ...
    }
    

    注解使用@+注解名可以标记在类、方法、属性甚至方法参数上。

    其中的@interface是一个关键字,这个关键字表示:这个东西是继承了java.lang.annotation.Annotation接口,表示它是一个注解。

    2、内置注解

    @Override 表示重写

    @Deprecated 表示已被废弃,不推荐使用

    @SuppressWarnings 用来抑制编译时的警告信息

    @FunctionalInterface 表示函数式接口

    @SafeVarargs 专门为抑制“堆污染”警告提供的

    3、元注解

    元注解就是用来修饰注解的注解,用来使该注解附带别的功能。比如我们看@overrid的源码:

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

    上面就有两个元注解。元注解有五种:

    1. @Retention

      意为保留、保持。即指定注解保留到什么阶段,是源码(编译)、字节码(类加载)还是运行阶段。

      // 注解仅存在于源码中,在class字节码文件中不包含
      @Retention(RetentionPolicy.SOURCE)
      // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
      @Retention(RetentionPolicy.CLASS)
      // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
      @Retention(RetentionPolicy.RUNTIME)
      

      如overrid注解只是一个标记作用,只是给阅读代码的人看的,所以只需要保留在源码阶段即可。

    2. @Target

      即注解的目标是谁。有这些:

      @Target(ElementType.TYPE)          //作用接口、类、枚举、注解
      @Target(ElementType.FIELD)         //作用属性字段、枚举的常量
      @Target(ElementType.METHOD)        //作用方法
      @Target(ElementType.PARAMETER)     //作用方法参数
      @Target(ElementType.CONSTRUCTOR)   //作用构造函数
      @Target(ElementType.LOCAL_VARIABLE)//作用局部变量
      @Target(ElementType.ANNOTATION_TYPE)//作用于注解
      @Target(ElementType.PACKAGE)       //作用于包
      @Target(ElementType.TYPE_PARAMETER)//作用于泛型,即泛型方法类接口, 1.8加入
      @Target(ElementType.TYPE_USE)      //可以用于标注任意类型除了class, 1.8加入
      
    3. @Document

      它的唯一作用是能够将注解中的元素包含到 Javadoc 中去。

    4. @Inherited

      表示这个注解具有继承性。即,如果一个类被具有继承性的注解标记了,则子类会继承父类的注解。

    5. @Repeatable

      表示这个注解具有重复性,即可以重复作用于一个对象多次,但每次注解的属性不同。

    4、自定义注解

    通过@interface标记该类是一个注解,假设自定义了一个注解如下:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Test {
          String name();
          int id() default 101;
          String[] friend() default {"Alis","Bob"};
    }
    

    4.1、属性

    注解里可以有它的属性,如上面的name、id、friend。属性写法要加上括号,后面还可以加上默认值。如果没有默认值,使用该注解时就要指定该属性的值。

    属性的类型可以为以下六种:基本数据类型,String,枚举类型,注解类型,Class类型,以上类型的一维数组类型。

    4.2、使用

    使用时在可以标注的位置使用该注解,并给出必要的参数。如上例,id、friend有默认参数,就可以只给出name。

    @Test(name = "cc")
    

    5、通过反射获取注解属性的值

    要获取某个注解属性的值就要从它修饰的东西入手(类、方法或属性),先通过反射获取到注解修饰的东西。反射获取到的对象可以使用下面几个方法:

    /**是否存在对应 Annotation 对象*/
    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
          return GenericDeclaration.super.isAnnotationPresent(annotationClass);
      }
    /**获取 Annotation 对象(如果只有一个)*/
    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
        Objects.requireNonNull(annotationClass);
    
        return (A) annotationData().annotations.get(annotationClass);
    }
    /**获取所有 Annotation 对象*/   
    public Annotation[] getAnnotations() {
        return AnnotationParser.toArray(annotationData().annotations);
    }
    

    仍以上述的Test注解为例,假设我们有一个User类,想通过注解给类传值进行参数设置:

    @Test(name = "cui")
    public class User {
        public String name;
    
        public User(){
            try {
    	    //获取注解修饰的类
                Class cls = Class.forName("com.User");
    	    //判断该类有没有注解修饰
                if(cls.isAnnotationPresent(JustTest.class)){
    	        //拿到这个注解
                    JustTest annotation = (JustTest) cls.getAnnotation(JustTest.class);
                    //获取注解中的属性并为name赋值
                    this.name = annotation.name();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    
  • 相关阅读:
    Oracle trunc()函数的用法
    Python获取指定目录下文件名,及创建目录
    python复制文件并重命名
    python自动创建Excel,且文件名和内容从另一个Excel中自动获取
    pip命令提示unknow or unsupported command install解决方法及查看包方法
    今日份学习性能测试工具、瀑布图
    Oracle的NVL函数用法
    创建虚拟机过程
    Linux中使用 alias 来简化测试部分工作
    排序-冒泡-java
  • 原文地址:https://www.cnblogs.com/cpcpp/p/14255042.html
Copyright © 2011-2022 走看看