美文网首页
Java注解

Java注解

作者: 挂云帆love | 来源:发表于2022-01-14 20:18 被阅读0次

    一、注解介绍

    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注解

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