Spring系列第16篇:深入理解java注解(预备知识)

本文详细介绍了Java注解的定义、使用范围、保留策略,包括如何定义参数、@Target和@Retention的用法。通过案例展示了注解在类、字段、方法等不同位置的应用,并探讨了注解信息的获取方法,帮助读者深入理解Java注解的各个方面。
摘要由CSDN通过智能技术生成

3个步骤:

  1. 定义注解

  2. 使用注解

  3. 获取注解信息做各种牛逼的事情

定义注解


关于注解的定义,先来几个问题:

  1. 如何为注解定义参数?

  2. 注解可以用在哪里?

  3. 注解会被保留到什么时候?

定义注解语法

jdk中注解相关的类和接口都定义在java.lang.annotation包中。

注解的定义和我们常见的类、接口类似,只是注解使用@interface来定义,如下定义一个名称为MyAnnotation的注解:

public @interface MyAnnotation {

}

注解中定义参数

注解有没有参数都可以,定义参数如下:

public @interface 注解名称{

[public] 参数类型 参数名称1() [default 参数默认值];

[public] 参数类型 参数名称2() [default 参数默认值];

[public] 参数类型 参数名称n() [default 参数默认值];

}

注解中可以定义多个参数,参数的定义有以下特点:

  1. 访问修饰符必须为public,不写默认为public

  2. 该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组

  3. 该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作)

  4. 参数名称后面的()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法

  5. default代表默认值,值必须和第2点定义的类型一致

  6. 如果没有默认值,代表后续使用注解时必须给该类型元素赋值

指定注解的使用范围:@Target

使用@Target注解定义注解的使用范围,如下:

@Target(value = {ElementType.TYPE,ElementType.METHOD})

public @interface MyAnnotation {

}

上面指定了MyAnnotation注解可以用在类、接口、注解类型、枚举类型以及方法上面,自定义注解上也可以不使用@Target注解,如果不使用,表示自定义注解可以用在任何地方

看一下@Target源码:

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Target {

ElementType[] value();

}

有一个参数value,是ElementType类型的一个数组,再来看一下ElementType,是个枚举,源码如下:

package java.lang.annotation;

/注解的使用范围/

public enum ElementType {

/类、接口、枚举、注解上面/

TYPE,

/字段上/

FIELD,

/方法上/

METHOD,

/方法的参数上/

PARAMETER,

/构造函数上/

CONSTRUCTOR,

/本地变量上/

LOCAL_VARIABLE,

/注解上/

ANNOTATION_TYPE,

/包上/

PACKAGE,

/类型参数上/

TYPE_PARAMETER,

/类型名称上/

TYPE_USE

}

指定注解的保留策略:@Retention

我们先来看一下java程序的3个过程

  1. 源码阶段

  2. 源码被编译为字节码之后变成class文件

  3. 字节码被虚拟机加载然后运行

那么自定义注解会保留在上面哪个阶段呢?可以通过@Retention注解来指定,如:

@Retention(RetentionPolicy.SOURCE)

public @interface MyAnnotation {

}

上面指定了MyAnnotation只存在于源码阶段,后面的2个阶段都会丢失。

来看一下@Retention

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Retention {

RetentionPolicy value();

}

有一个value参数,类型为RetentionPolicy枚举,如下:

public enum RetentionPolicy {

/注解只保留在源码中,编译为字节码之后就丢失了,也就是class文件中就不存在了/

SOURCE,

/注解只保留在源码和字节码中,运行阶段会丢失/

CLASS,

/源码、字节码、运行期间都存在/

RUNTIME

}

使用注解


语法

将注解加载使用的目标上面,如下:

@注解名称(参数1=值1,参数2=值2,参数n=值n)

目标对象

直接来案例说明。

无参注解

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@interface Ann1 { //@1

}

@Ann1 //@2

public class UseAnnotation1 {

}

@1:Ann1为无参注解

@2:类上使用@Ann1注解,没有参数

一个参数的注解

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@interface Ann2 { //@1

String name();

}

@Ann2(name = “我是路人甲java”) //@2

public class UseAnnotation2 {

}

一个参数为value的注解,可以省略参数名称

只有一个参数,名称为value的时候,使用时参数名称可以省略

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@interface Ann3 {

String value();//@1

}

@Ann3(“我是路人甲java”) //@2

public class UseAnnotation3 {

}

@1:注解之后一个参数,名称为value

@2:使用注解,参数名称value省略了

数组类型参数

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@interface Ann4 {

String[] name();//@1

}

@Ann4(name = {“我是路人甲java”, “欢迎和我一起学spring”}) //@2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值