Java注解

2020-09-25  本文已影响0人  Android_Gleam

1.注解是什么,有什么意义

注解本身没有任何意义,单独的注解就是一种注释,他需要结合其他如反射、插桩等技术才有意义。

Java 注解(Annotation)又称 Java 标注,是 JDK1.5 引入的一种注释机制。是元数据的一种形式,提供有关于程序但不属于程序本身的数据。注解对它们注解的代码的操作没有直接影响。

2.注解的定义

注解的定义很简单,我们直接使用@interface关键字就可以定义一个注解。
public @interface Test {}
这只是注解的简单定义,这么写是没有任何意义的,我们还需要加入其它的配置才可以。我们往下看。

3.元注解

在定义注解时,注解类也能够使用其他的注解声明。对注解类型进行注解的注解类,我们称之为 meta-annotation(元注解)。

@Target

注解标记另一个注解,以限制可以应用注解的 Java 元素类型。目标注解指定以下元素类型之一作为其值:

下面我们看下Target的源码

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

由上面的源码可知Target可以指定多个,因为它的值是数组

@Retention

注解指定标记注解的存储方式:

使用场景

注解处理器运行在编译阶段:java文件经过javac编译成.class文件,
javac采集到所有的注解信息,包装成一个节点(Element),再由javac调用指定的注解处理程序。javac编译java文件的时候会调用注解处理器,然后在编译为class文件。所以注解处理器使用源码级别的注解就可以了。
还有就是编译器代码检查,例如IntDef、@DrawableRes,语法检查是由ide或者ide插件实现的。

@Inherited

一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。

/**
 * 自定义注解
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyTestAnnotation {
}

/**
 * 父类标注自定义注解
 */
@MyTestAnnotation
public class Father {}

//子类
class Son extends Father{}

public static void main(String[] args) {
        //获取Son的class对象
        Class<Son> sonClass = Son.class;
        // 获取Son类上的注解MyTestAnnotation可以执行成功
        boolean annotation = sonClass.isAnnotationPresent(MyTestAnnotation.class);
        //打印值为true
        System.out.println(annotation);
}

@ Repeatable

被这个元注解修饰的注解可以同时作用一个对象多次

//Persons
@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)
public   @interface Persons {
    Person[] value();
}

//Person注解
@Repeatable(Persons.class)
public  @interface Person{
    String role() default "";
}


@Person(role="shuaige")
@Person(role="shuaibi")
@Person(role="dashuaige")
@Person(role="dashuaibi")
public  class ShuaiGe {
    String name="";
}

public static void main(String[] args) {
        if (ShuaiGe.class.isAnnotationPresent(Persons.class)) {
            Persons p2 = Man.class.getAnnotation(Persons.class);
            for (Person t : p2.value()) {
                System.out.println(t.role());
            }
        }
}

@Documented

用于被javadoc工具提取成文档。

4.注解类型元素

在上文元注解中,允许在使用注解时传递参数。我们也能让自定义注解的主体包含 annotation type element (注解 类型元素) 声明,它们看起来很像方法,可以定义可选的默认值。

@Target({ElementType.TYPE,ElementType.FIELD}) 
@Retention(RetentionPolicy.SOURCE) 
public @interface ShuaiGe { 
    String value(); //无默认值 
    int age() default 1; //有默认值 
}

注意:在使用注解时,如果定义的注解中的类型元素无默认值,则必须进行传值。

@Lance("帅") //如果只存在value元素需要传值的情况,则可以省略:元素名= 
@Lance(value="帅",age = 2)
int i;
上一篇 下一篇

猜你喜欢

热点阅读