首页 > 编程知识 正文

Java注解使用,java 自定义注解

时间:2023-05-03 12:42:24 阅读:158460 作者:1124

TL; 灾难恢复

Java注释广泛用于开发,用于增强变量/方法/类等。

尝试说明如何使用Java自定义注释以及如何在开源项目中使用它们。

本文主要记录个人的理解,全文基于Java SE8。

自定义注释

自定义注释分为注释声明和注释处理逻辑两部分。

每个注释可以有多个属性值,同名的注释在声明后可以在对象中使用多个。

注释结构

定义注释

用以下例子进行说明。

1

2

3

4

5

6

7

8

9

10 @ repeatable (learnrepeatableannotation.class ) )。

@ retention (retention policy.runtime ) )。

@target(elementtype.field,ElementType.LOCAL_VARIABLE,ElementType.METHOD} ) )

公共@ interfacelearnannotation {

String value () default ' );

字符串文件定义值() default );

Class className () default Void.class;

}

逐行分析一下。

@ repeatable (learnrepeatableannotation.class )表示此注释可以在一个对象中多次使用。 具体内容将在后面详细说明。

@ retention (retention policy.runtime )是一个元注释,表示在运行时可以在反射中使用注释。 稍后将详细讨论元注释。

@target(elementtype.field,ElementType.LOCAL_VARIABLE,ElementType.METHOD} ) )的注释可以存在于属性、局部变量和方法中

public @interfacelearnannotation表示这是一个注释声明,注释必须用@ interface声明。

String value () default ' ); 表示注释的值域是字符串类型,默认为空字符串。 使用注释时,可以以属性名称=值的形式赋值。 如果不声明属性名称,说明将分配给value属性。 注释中的属性名称是声明中的方法名称。

字符串文件定义值() default ); 表示自定义注释的@LearnAnnotation具有名为filedAnnotationValue的字符串属性,可以以@ learn annotation (filedannotationvalue=' name ' )的形式使用

Class className () default Void.class; 表示自定义注释的@LearnAnnotation有一个名为ClassName的class对象。 请注意,自定义注释的属性值仅限于基本类型(例如short/int/long/boolean/char/string/enum/class )

如果注释中没有default声明,则在使用之前必须指定属性值。

对同一对象使用多个相同的注释声明

同样在上述情况下,第一行中的@ repeatable (learnrepeatableannotation.class )使用@LearnRepeatableAnnotation注释在一个对象中显示多个

@LearnRepeatableAnnotation的实现如下。

1

2

3

4

5 @ retention (retention policy.runtime ) )。

@target(elementtype.field,ElementType.LOCAL_VARIABLE,ElementType.METHOD} ) )

公共@ interfacelearnrepeatableannotation {

学习分析[ ] value () default {} );

}

这意味着您需要声明新类型的注释。 此注释的值是计划使用多个注释的数组。

在实际使用中,可以通过以下形式使用。

1

2

3 @ learn annotation (filedannotationvalue=' v1 ' ) ) ) ) ) ) )3@ learn annotation (filedannotationvalue=' value ) ) ) )

@learnannotation(value='V2 ' ) ) ) ) ) ) ) ) ) ) ) ) @learnannotation(value='V2 ' ) ) ) )

私有int testrepeatint=0;

使用多个同名注解(例如,配置规则)可以使当前对象获得多个规则。

声明评论

注解声明又主要分为两个部分:元注解注解名称及字段定义。

元注解

Java 中提供了4种元注解:

@Documented - 在JavaDoc中提供注解信息

@Retention - 注解的生效范围

@Target - 注解允许使用的对象

@Inherited - 注解是否可以被子类继承

元注解是实现自定义注解的重要工具,最重要的是@Retention与@Target。

元注解@Retention

元注解 @Retention 可以有如下3个属性值:

RetentionPolicy.SOURCE – 注解保留在源码中,编译阶段会被丢弃

RetentionPolicy.CLASS – 注解保留在.class文件中,但不会在运行时存在

RetentionPolicy.RUNTIME – 注解可以在运行时读取、使用反射可以获得

默认是RetentionPolicy.CLASS。

在注解指定了 RetentionPolicy.SOURCE 的情况下,Java 编译源码时,会有一个注解处理阶段,会调用对应的注解处理器(继承自javax.annotation.processing.AbstractProcessor的子类),在编译时,可以执行注解的一些逻辑,例如生成代码。

在 IDEA 中,如果是 maven 项目,可以通过项目配置指定注解处理器,也可以通过 maven-processor-plugin 实现。

元注解@Target

元注解 @Target 可以有如下8个属性值:

ElementType.ANNOTATION_TYPE

ElementType.CONSTRUCTOR

ElementType.FIELD

ElementType.LOCAL_VARIABLE

ElementType.METHOD

ElementType.PACKAGE

ElementType.PARAMETER

ElementType.TYPE

作用范围看名称基本都能对应上。默认是全部。

开源项目中的使用

Fastjson

Fastjson 作为广泛使用的 Java JSON 解析类库,广泛应用了注解。

字段别名

POJO 中如果使用驼峰命名,但是 API 中需要使用下划线分隔,这样的场景并不少见。

Fastjson 中通过 @JSONField 注解可以实现这一功能。

Fastjson 通过 toJSONString() 方法实现对象转化到 JSON 格式字符串的行为,首先会根据转换对象的类型解析出对象各个字段的信息(参见com.alibaba.fastjson.util.FieldInfo),读取每个字段上的 @JSONField 注解,在转化为字符串过程中,当需要写入键时,如果注解 name 值存在,则写入 name 配置的值。

Spring

AOP

AOP 是常用的编程模式。

在 Spring 中定义一个 Aspect,通过 @Pointcut 注解关联何种对象的何种操作,通过 @Before/@After 等注解指定当前 Aspect 各个阶段可以执行的方法(Advice)。

Spring 框架在扫描各个 bean 时,会根据指定的 Aspect 信息,为各个 bean 的指定方法关联上各个 Advice,在执行时逐个运行。

例如对外提供接口调用时,需要对一些接口提供自定的参数校验等功能,可以考虑通过自定义注解的方式,提供一个 @Around advice,判断参数是否合理即可。

Lombok

Java 开发中对象的 Getter/Setter 方法以及常规的构造方法让代码变得臃肿,Lombok 通过注解的方式,在编译阶段修改 AST,实现生成的 class 文件中带有对应的方法。

以上内容还可以另起篇幅详细说明。

参考

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。