欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义注解

程序员文章站 2022-06-17 08:34:08
...

如果要自定义一个注解,首先要明白注解怎样定义,也就是注解定义时的格式。

先来看一个Spring框架的注解@Component。

           自定义注解

可以看到,定义注解有两个关键点:元注解、方法(在注解中又叫属性)。

注解的属性(接口中的方法)

一直都在强调,注解的本质是接口,所以,它的内部可以声明方法,在注解中,这些方法又叫做属性。

public @interface TestAnnotation {
    String value();
}

声明这个方法(属性)又有什么用?为了探究它有什么用,先使用一下这个注解。

                    自定义注解

报错的原因是没有给value这个属性赋值,所以要给它赋值

                     自定义注解

再次返回到注解的定义中,看到value方法的返回值类型是String。在使用时(赋值时),要与方法返回值的类型一致。

如果注解只有一个属性,并且这个属性的名称是value,则在使用时,可以在括号中直接写值。

也就是说,对于上面的例子,可以这样使用

@Target("hello")  //等价于@Target(value = "hello")

除此之外,还可以设置方法返回默认值,也就是这个属性的默认值。

public @interface TestAnnotation {
    String value() default "hello";
}

在方法声明后跟上default关键字,在default关键字后加上默认的返回值(或者说是默认的属性值)。

如果一个属性有了默认值,如果不显示给这个默认值赋值,就会使用默认值,而不会像上面那样报错。

返回值类型(属性类型)的限制:在注解中,返回值的类型只能是:简单类型、String、枚举类型、注解以及它们的数组

关于怎样读取这些值,在后面的注解解析中学习,现在只需要知道怎么定义,怎么使用即可

元注解

元注解,本身也是注解,它用来注解定义是说明注解。Java提供了4种预定义的元注解。

@Target

@target用来说明注解修饰代码的哪个部分。(也就是注解可以出现的位置,例如:@Overide是用来修饰方法的。通过这个元注解,指定注解可以修饰类、字段、方法)

@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {

    ElementType[] value();
}

自己标记自己?(此处禁止套娃)这里表示@Target这个注解作用的类型时ANNOTATION_TYPE,也就是作用于注解

这是Target注解的部分定义,@Taget只有一个属性value,它的类型是ElementType的一个数组。根据之前的分析,value的类型只能是简单类型、String、枚举和注解。

在使用时,从@Target(ElementType.ANNOTATION_TYPE)可以推断,它是一个枚举类型。

通过追溯,可以看到它的确是一个枚举类型。通过枚举,限定了value属性的取值。

注解中声明value是一个数组,在使用的时候为什么直接使用了一个值?

通常,对于一个数组赋值,因该使用大括号:

@Target({ElementType.ANNOTATION_TYPE})

如果大括号中只有一个值,可以省略大括号

@Target最常用的value属性值:
1. ElementType.TYPE:说明注解作用于类(或接口)。
2. ElementType.METHOD:说明注解作用于方法。
3. ElementType.FIELD:说明注解作用于字段。

@Retention

@Retention用来说明注解保存的位置(或时间长短)。注解可以仅保存在源代码中,供编译器识别(例如Override);注解可以保存在字节码文件中(即已经被编译),运行时,JVM不需要读取(加载);注解在运行是被JVM读取,可以通过反射进行使用。(关于如何使用,放到后面的注解解析部分)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {

    RetentionPolicy value();
}

这个注解的属性是一个枚举类型RententionPolicy,他总共有三个值SOURCE,CLASS和RUNTIME。对应于上面说到的源码、字节码、运行时。

@Document

@Document,用来说明注解是否会出现在文档中。当使用javadoc工具生成文档时,如果只有被@Document修饰的注解,才会出现在文档中。

@Inherited

@Inherited,如果一个注解被@Inherited修饰,当这个注解作用于一个类/接口,那么这个类的子类都会自动的被这个注解修饰。

目前为止,至少可以读懂一个注解(有哪些属性,作于在什么地方),可以自定义一个有属性的注解

相关标签: java