java四个元注解的作用_JAVA 中四个『元注解』

本文详细解释了JAVA中的四个元注解:@Target、@Retention、@Documented 和 @Inherited 的含义及使用方法。@Target 用于指定注解的作用范围;@Retention 定义了注解的生命周期;@Documented 控制注解是否包含在文档中;@Inherited 使注解具备继承特性。

JAVA 中有以下四个『元注解』:

@Target:注解的作用目标

@Retention:注解的生命周期

@Documented:注解是否应当被包含在 JavaDoc 文档中

@Inherited:是否允许子类继承该注解

其中,@Target 用于指明被修饰的注解最终可以作用的目标是谁,也就是指明,你的注解到底是用来修饰方法的?修饰类的?还是用来修饰字段属性的。

@Target 的定义如下:

f6b991926246cafebe8a8b01b7a052c3.png

我们可以通过以下的方式来为这个 value 传值:

@Target(value = {ElementType.FIELD})

被这个 @Target 注解修饰的注解将只能作用在成员字段上,不能用于修饰方法或者类。其中,ElementType 是一个枚举类型,有以下一些值:

ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上

ElementType.FIELD:允许作用在属性字段上

ElementType.METHOD:允许作用在方法上

ElementType.PARAMETER:允许作用在方法参数上

ElementType.CONSTRUCTOR:允许作用在构造器上

ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上

ElementType.ANNOTATION_TYPE:允许作用在注解上

ElementType.PACKAGE:允许作用在包上

@Retention 用于指明当前注解的生命周期,它的基本定义如下:

8a89c683972c1c1a01abae7ec1968d30.png

同样的,它也有一个 value 属性:

@Retention(value = RetentionPolicy.RUNTIME

这里的 RetentionPolicy 依然是一个枚举类型,它有以下几个枚举值可取:

RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件

RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件

RetentionPolicy.RUNTIME:永久保存,可以反射获取

@Retention 注解指定了被修饰的注解的生命周期,一种是只能在编译期可见,编译后会被丢弃,一种会被编译器编译进 class 文件中,无论是类或是方法,乃至字段,他们都是有属性表的,而 JAVA 虚拟机也定义了几种注解属性表用于存储注解信息,但是这种可见性不能带到方法区,类加载时会予以丢弃,最后一种则是永久存在的可见性。

剩下两种类型的注解我们日常用的不多,也比较简单,这里不再详细的进行介绍了,你只需要知道他们各自的作用即可。@Documented 注解修饰的注解,当我们执行 JavaDoc 文档打包时会被保存进 doc 文档,反之将在打包时丢弃。@Inherited 注解修饰的注解是具有可继承性的,也就说我们的注解修饰了一个类,而该类的子类将自动继承父类的该注解。

<think>我们被要求详细解释Java中的四个注解(Meta-Annotations)。注解是用于注解其他注解注解,在`java.lang.annotation`包中定义。Java标准库提供了四个注解: 1. `@Target` - 指定注解可以应用的范围(如类、方法、字段等) 2. `@Retention` - 指定注解的保留策略(源码、编译时、运行时) 3. `@Documented` - 表示该注解应该被包含在Javadoc中 4. `@Inherited` - 表示该注解可以被子类继承 此外,在Java 8中新增了`@Repeatable`注解,但问题要求的是四个,所以我们主要介绍上述四个。 下面我们逐个详细说明,并给出代码示例。 </think>### Java中的四个注解详解 在Java中,注解(Meta-Annotations)是用于注解其他注解的特殊注解,它们提供了关于注解本身的信息。Java在`java.lang.annotation`包中定义了四个核心注解: #### 1. `@Target` - 指定注解适用范围 ```java @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); } ``` **功能**: 定义注解可以应用的位置(类、方法、字段等) **参数**:`ElementType`枚举值数组: - `TYPE`:类、接口、枚举 - `FIELD`:字段(包括枚举常量) - `METHOD`:方法 - `PARAMETER`:参数 - `CONSTRUCTOR`:构造器 - `LOCAL_VARIABLE`:局部变量 - `ANNOTATION_TYPE`:注解类型 - `PACKAGE`:包声明 - `TYPE_PARAMETER`:类型参数(JDK8+) - `TYPE_USE`:类型使用(JDK8+) **示例**: ```java @Target({ElementType.METHOD, ElementType.TYPE}) public @interface CustomAnnotation { // 该注解可用在类和方法上 } ``` #### 2. `@Retention` - 定义注解生命周期 ```java @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); } ``` **功能**: 指定注解的保留策略 **参数**:`RetentionPolicy`枚举值: - `SOURCE`:仅保留在源码中(编译时丢弃) - `CLASS`:保留在字节码中(默认值,运行时不可见) - `RUNTIME`:保留到运行时(可通过反射读取) **示例**: ```java @Retention(RetentionPolicy.RUNTIME) public @interface RuntimeVisibleAnnotation { // 该注解在运行时可通过反射获取 } ``` #### 3. `@Documented` - 包含在Javadoc中 ```java @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { } ``` **功能**: 标记注解是否应包含在生成的Javadoc中 **特点**: - 无参数 - 仅作为标记注解使用 - 不影响注解的运行时行为 **示例**: ```java @Documented public @interface IncludeInJavaDoc { // 使用该注解素会在Javadoc中显示注解信息 } ``` #### 4. `@Inherited` - 注解继承 ```java @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { } ``` **功能**: 允许子类继承父类上的注解 **规则**: - 仅对类级别的注解有效 - 不适用于接口或方法 - 子类继承父类注解的前提是父类注解使用了`@Inherited` **示例**: ```java @Inherited @Retention(RetentionPolicy.RUNTIME) public @interface InheritableAnnotation {} @InheritableAnnotation class ParentClass {} class ChildClass extends ParentClass { // 自动继承@InheritableAnnotation } ``` ### 完整使用示例 ```java import java.lang.annotation.*; // 定义自定义注解 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface ApiVersion { double value() default 1.0; String since() default "2023-01-01"; } // 使用注解 @ApiVersion(value = 2.5, since = "2023-06-15") public class PaymentService { @ApiVersion(1.8) public void processPayment() { // 方法实现 } } // 注解处理器示例 public class AnnotationProcessor { public static void main(String[] args) { Class<PaymentService> clazz = PaymentService.class; // 获取类上的注解 ApiVersion classAnnotation = clazz.getAnnotation(ApiVersion.class); System.out.println("Class version: " + classAnnotation.value()); // 获取方法上的注解 try { ApiVersion methodAnnotation = clazz.getMethod("processPayment") .getAnnotation(ApiVersion.class); System.out.println("Method version: " + methodAnnotation.value()); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } ``` ### 注解关系图 ``` @Target │ ├─ 定义注解应用位置 │ @Retention │ ├─ 定义注解生命周期 │ @Documented │ ├─ 控制Javadoc包含 │ @Inherited │ └─ 控制注解继承 ``` ### 关键注意事项: 1. **组合使用**:注解通常组合使用,例如`@Target`+`@Retention`是最常见组合 2. **默认行为**:未指定`@Retention`时默认为`RetentionPolicy.CLASS` 3. **继承限制**:`@Inherited`只对类有效,对接口实现无效 4. **JDK8扩展**: - `@Repeatable`:允许同一位置重复使用注解 - `ElementType.TYPE_PARAMETER`:支持泛型类型参数注解 - `ElementType.TYPE_USE`:支持任何类型使用注解
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值