Java注解

一、注解介绍

Java注解(Annotation)又称 Java 标注。Java 语言中的类、方法、变量、参数和包等都可以被标注。

1.1、注解写法

格式:

@Target 注解标注的目标:类、方法、变量、参数和包等
@Retention 作用域:源码、编译时、运行时
public @interface 注解名称{
    属性列表;
}

注解通过 @interface 关键字进行定义,如下,定义一个MyAnnotation的注解:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    int value() default -1;
    String name();
}

@Target、@Retention,也是元注解,元注解是可以注解到注解上的注解。

@Target

Target 目标,限定注解了标注的地方。取值如下:

  • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
  • ElementType.CONSTRUCTOR 可以给构造方法进行注解
  • ElementType.FIELD 可以给属性进行注解
  • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
  • ElementType.METHOD 可以给方法进行注解
  • ElementType.PACKAGE 可以给一个包进行注解
  • ElementType.PARAMETER 可以给一个方法内的参数进行注解
  • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

@Target 可以给多个值,注解到多个地方,如

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}

@Retention

Retention 英文意为保留,标识注解作用域,在什么时候有效。取值如下:

  • RetentionPolicy.SOURCE 注解只在源码阶段保留,并被编译器忽略。
  • RetentionPolicy.CLASS 注解在源码阶段、编译器进行编译时保留,它并不会被加载到 JVM 中。
  • RetentionPolicy.RUNTIME 注解在源码阶段、编译器进行编译、运行时保留,运行时,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。

SOURCE < CLASS < RUNTIME,即CLASS包含了SOURCE,RUNTIME包含SOURCE、CLASS。

@interface

定义注解时,用@interface定义

注解的属性

注解可以定义一些属性,如value、name:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    int value() default -1;
    String name();
}

default 指定了默认值

1.2、注解的使用

我们定义一个注解,简单的使用,如下:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    int value() default -1;
}


//使用注解 MyAnnotation
public class MyAnnotationTest {

    @MyAnnotation(value = 1)
    private int age;

    @MyAnnotation
    private int age1;
    
    ......
}

Android元注解的使用

在Android中,系统源码帮我们定了一些元注解,如:IntDef, LongDef, StringDef,可以限定参数的取值范围,可以减少使用枚举,减少内存。

如,我们定义一个星期:

    public static final int Sunday = 0;
    public static final int Monday = 1;
    public static final int Tuesday = 2;
    public static final int Wednesday = 3;
    public static final int Thursday = 4;
    public static final int Friday = 5;
    public static final int Saturday = 6;
    

再定义一个注解,限定使用这个注解时的取值,若不是限定的值,则源码就会报红:

    @IntDef({Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday})
    @Target({ElementType.PARAMETER, ElementType.FIELD})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Week {
    }

注解Week的使用:

    @Week
    private static int weekDay = Saturday;

    public static void setWeekDay(@Week int weekDay){
        AnnotationUsageDemo.weekDay = weekDay;
    }
    
    
    public static void main(String[] args) {
        //报红,须使用:Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
        //setWeekDay(5);

        //正确
        setWeekDay(Friday);
    }

不使用限定值,报红,如图:

1.png

1.3、注解的用法

注解单独使用是没有意义的,常见的用法:

  • 注解+开发工具(AS),用于源码期,做一些代码校验等,如注解:ResId、IntDef等
  • 注解+APT 用于编译期时生成一些代码文件,如:butterknife、dagger2、hilt、databinding
  • 注解+字节码操作 用于编译时字节码插桩,如:AspectJ、ARounter、CC
  • 注解+反射 代码运行时,通过反射,进行相应的处理,如:XUtils、Lifecycle

你可能感兴趣的:(Java注解)