美文网首页
注解概述

注解概述

作者: jxiang112 | 来源:发表于2022-04-06 14:01 被阅读0次

什么是注解

注解(Annotation)也叫元数据,它是一种对代码级别的说明。JDK1.5开始引入的一种特性。与类、接口、枚举属同一级别,它可以声明在包、类、接口、字段、方法、局部变量、方法参数的前面,用于对这些代码元素进行说明。

注解的用途

注解常见的用途有编译时代码校验(如:@Override等)、编译时自动生成代码(如Arouter、EventBus等)、运行时获取注解信息等。

Java常见的自带注解

  • @Override:它用于编译时多态重写语法进行校验,校验不通过则编译失败
  • @Deprecated:它用于对类、接口、字段、方法等进行说明,说明这些元素已经过时或者在新版本中已经被抛弃,不推荐再使用,而是使用新的方案。
  • @SuppressWarnings:它用于对类、接口、方法等进行说明,为的是阻止编译器发出某些警告。

自定义注解

注解定义

注解的用途还是挺广泛的,可以对代码解耦、面向切面编程(AOP)等,所以我们可以根据需要自行创建注解。定义注解与定义接口的语法差不多,不同在于注解在interface前面多加了个@符合,如下所示:

public @interface TestAnnotation {
    int value() default 1;
}

注解实际上也属于接口,它继承的是java.lang.annotation.Annotation,我们通过javap进行反编译可以得到印证:

E:\project\demo\test1\app\src\main\java\com\wyx\test1\annotation>javap TestAnnotation.class
Compiled from "TestAnnotation.java"
public interface com.wyx.test1.annotation.TestAnnotation extends java.lang.annotation.Annotation {
 public abstract int value();
}
注解属性

注解的属性相对比较特殊,它是以抽象方法的形式进行定义,设置默认值在其后面加上default xxx即可,如上面的代码举例。

注解属性类型

注解属性支持的类型有:

  • 基本数据类型(boolean、byte、short、int、long、float、double、char)
  • String
  • 枚举
  • 注解
  • 上述类型的数组
    注意:不支持class、interface、基本类型的装箱类(如Byte、Integer等)

注解的使用

定义好注解之后,就可以应用在程序元素的上面,用于的元素进行说明,如:

@TestAnnotation
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

上面的代码中@TestAnnotation注解应用在MainActivity类的上面,对MainActivity类进行注解说明。
使用注解分为标记注解、单值注解、多值注解:

标记注解

标记注解指没有属性的注解,一般用于对元素进行标记,标记元素拥有此注解,如@Override:

public @interface Override {
}

使用标记注解时,直接在元素上加上标间注解即可,如@Override:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
单值注解

单值注解指只有一个属性的注解,一般以value()作为属性,如:

@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation {
    int value() default 1;
}

使用单值注解时,如果属性有默认值且使用默认值,则可以省略对属性的赋值。如:

@TestAnnotation
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

此时MainActivity的注解@TestAnnotation中的属性value值使用的是默认值即1。
如果属性没有默认值,则在使用是必须对属性进行赋值。
如果对属性进行赋值,则在使用注解时,加上括号,括号内使用key=value(其中key是注解定义的属性名称,value是属性类型的值)的形式进行赋值,如:

@TestAnnotation(value = 2)
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

此时MainActivity的注解@TestAnnotation中的属性value被赋值为2。

多值注解

多值注解指有多个属性的注解,如下所示:

@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation {
    int value() default 1;
    String name() default "";
    int[] array();
}

使用多值注解时,如果属性有默认值且使用默认值,则可以忽略对属性的赋值;如果属性没有默认值则必须对属性进行赋值,多属性的赋值与单属性赋值差不多,也是在括号中进行赋值,但是以key1=value1, key2=value2的形式,如下所示:

@TestAnnotation(value = 2, name = "test", array = {1, 2, 3})
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

上述对时MainActivity 的注解@TestAnnotation的属性进行了赋值,此时MainActivity 的注解@TestAnnotation的属性value值为2,属性name值为test,属性array的值为[1,2,3]。
注意如果属性是数组的形式,那么在对赋值时需要采用花括号进行赋值(如{xxx, xxx})。

元注解分类

元注解是指用来描述注解的注解。一般元注解是用来限定注解的使用范围、生命周期等。
jdk定义了如下四种类型的元注解:

元注解 描述
@Target 指定被修饰的注解的作用范围
@Retention 指定被修饰的注解的生命周期
@Documented 指定被修饰的注解是可以被Javadoc等工具文档化
@Inherited 指定被修饰的注解对程序元素进行修饰说明时,是可以被子类继承的
@Target

@Target 指定被修饰的注解的作用范围。
@Target是一个单值注解,属性名称是value,属性类型为ElementType[],表示注解可以限定于某一类型元素,也可限定作用于某几种类型元素。@Target的源码如下:

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

@Target可取的属性值可以在ElementType的源码中查看:

属性值 描述
TYPE 限定作用于:类、接口、注解、枚举的声明
FIELD 限定作用于:属性(包括枚举常量)的声明
METHOD 限定作用于:方法
PARAMETER 限定作用于:形式参数的声明
CONSTRUCTOR 限定作用于:构造函数的声明
LOCAL_VARIABLE 限定作用于:局部变量的声明
ANNOTATION_TYPE 限定作用于:注解类型的声明
PACKAGE 限定作用于:包声明
TYPE_PARAMETER 限定作用于:类型参数声明
TYPE_USE 限定作用于:类型的使用

一般常用的是TYPE 、FIELD 、METHOD 、PARAMETER

@Retention

@Retention 指定被修饰的注解的生命周期。
@Retention也是一个单值注解,其属性名称为value,属性类型为RetentionPolicy,@Retention的源码如下:

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

@Retention可取的属性值可以在RetentionPolicy的源码中查看:

属性值 描述
SOURCE 注解只保留在源码阶段,编译器编译之后就会被丢弃忽视。
CLASS 注解被编译器编译并保留在class文件中,但在JVM运行时会被丢弃忽视。
RUNTIME 注解会被保留到运行时,它会被加载进JVM中,可以在程序运行时通过反射获取到注解信息

注解自动生成代码

注解自动生成代码的原理是:将注解生命周期限定至少为CLASS时,再通过编译时APT(Annotation Process Tool,编译期注解处理器)技术获取源码中的注解的信息,根据规则自动生成代码。
此技术将会在后面的“Arouter之自动生成代码原理”进行详细的介绍。

运行时获取注解信息

运行时获取注解信息主要是在运行期间通过反射获取注解信息,这里需要将注解的生命周期限定为RUNNING。
下列代码是运行时获取注解信息的例子:

@TestAnnotation(value = 2, name = "test", array = {1, 2, 3})
public class TestAn {
    public static void main(String[] args) {
        Log.d("TestAn", "in main method");
        Class claz = TestAn.class;
        TestAnnotation an = (TestAnnotation) claz.getAnnotation(TestAnnotation.class);
        System.out.printf("TestAnnotation value: %d, name: %s\n", an.value(), an.name());
    }
}

相关文章

  • 注解

    目录 注解概述 内置注解 元注解 自定义注解 1 注解概述 作用 不是程序本身,可对程序作出解释 可别其他程序读取...

  • 注解概述

    注解概述 Annotation就是指注解,使用注解时在前面增加@符号 JDk5.0开始增加了对元数据(MetaDa...

  • 注解概述

    什么是注解 注解(Annotation)也叫元数据,它是一种对代码级别的说明。JDK1.5开始引入的一种特性。与类...

  • Java注解

    Java注解(Annotation)详解(一)——概述及JDK自带注解 Java注解(Annotation)详解(...

  • 优雅编程 - 组件扫描&拦截器

    示例形式概述注解扫描,注解切面组件。 SpringBean注解扫描组件 Spring中bean注解扫描类Class...

  • 一图看懂SpringBootApplication启动原理

    概述 剖析@SpringBootApplication注解 首先分析springboot的启动注解@SpringB...

  • java基础-day28-注解

    注解 1. 注解概述 1.1 注解解释 1.2 注解作用 1.3 Java中预定义的一些注解 2. Java中自定...

  • Java 注解 Annotation

    概述 了解 Java 注解前必须先了解元注解。元注解:描述注解的注解。 如果明白元数据概念就比较好理解元注解元数据...

  • Android-Retrofit

    概述 Retrofit 通过注解将 Java Interface API 调用转化为 HTTP Call ,注解提...

  • 打造一个简易的编译时注解框架(一)

    一、AbstractProcessor 1,概述 注解分为编译时注解和运行时注解,现在流行的主流框架ButterK...

网友评论

      本文标题:注解概述

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