大家好,欢迎来到IT知识分享网。
1 注解的基本概念
1.1 描述
自定义注解是指开发人员可以根据自己的需求定义一些标记,用来标识某些类、方法、变量等,在代码编写和执行的过程中,可以读取这些注解信息,从而实现一些特定的功能。注解是一种元数据,它不直接影响程序代码的执行,但可以为代码提供额外的信息或指示,使代码具有更多的灵活性和可扩展性。在Java中,注解的使用非常广泛,常见的注解包括:@Override、@Deprecated、@SuppressWarnings等。自定义注解的语法格式为:@interface 自定义注解名 {}。需要注意的是,自定义注解也可以定义属性,语法格式为:@interface 自定义注解名 {数据类型 属性名() default 默认值;}。在使用自定义注解时,需要调用注解类的属性方法来获取注解的属性值。
1.2 使用范围
这里是引用注解可以在Java程序中的类、方法、构造函数、成员变量、参数等多个位置使用,并且可以限定使用范围来增强注解的作用力。常见的注解使用范围如下:
- @Target注解:该注解用于限定注解的使用范围,可以设置的取值有CONSTRUCTOR、FIELD、LOCAL_VARIABLE、METHOD、PACKAGE、PARAMETER、TYPE等。
- @Retention注解:该注解指定了注解的保存方式,即生命周期,可以设置的取值有SOURCE、CLASS、RUNTIME,其中RUNTIME表示注解信息在运行时可以通过反射获取。
- @Documented注解:该注解用于指定注解是否包含在Java文档中。
- @Inherited注解:该注解表明被注解的类可以被子类继承,这样子类就具有了同样的
2 如何自定义注解
@Target({
ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MethodInfo {
String author() default "Unknown"; String version() default "1.0"; }
注:@interface 在底层实现上,所有定义的注解都会自动继承java.lang.annotation.Annotation接口。
这样就定义了一个名为MethodInfo的注解,其中包含了两个元素:作者和版本号,并且都有默认值。可以在使用该注解时,给元素传入具体的值,例如:
@MethodInfo(author = "张三", version = "1.2") public void doSomething() {
// 方法体 }
通过这种方式,就可以自定义注解并在代码编写和执行过程中使用它们了。
3 常用元注解
@Target
在上述例子中,可以看到注解上使用@Target修饰。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target {
/ * Returns an array of the kinds of elements an annotation type * can be applied to. * @return an array of the kinds of elements an annotation type * can be applied to */ ElementType[] value(); }
源码中可以看出,需要配置属性。ElementType:表示自定义注解所能够修饰的对象类型
public enum ElementType {
/ 类,接口(包括注解类型)或枚举的声明 */ TYPE, / 属性的声明 */ FIELD, / 方法的声明 */ METHOD, / 方法形式参数声明 */ PARAMETER, / 构造方法的声明 */ CONSTRUCTOR, / 局部变量声明 */ LOCAL_VARIABLE, / 注解类型声明 */ ANNOTATION_TYPE, / 包的声明 */ PACKAGE, / 类型参数声明(jdk1.8加入) */ TYPE_PARAMETER, / 任意类型(jdk1.8加入) */ TYPE_USE }
@Retention
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention {
/ * Returns the retention policy. * @return the retention policy */ RetentionPolicy value(); }
RetentionPolicy源码:
public enum RetentionPolicy {
/ 注解将被编译器忽略掉 */ SOURCE, / 注解将被编译器记录在class文件中,但在运行时不会被虚拟机保留,这是一个默认的行为 */ CLASS, / 注解将被编译器记录在class文件中,而且在运行时会被虚拟机保留,因此它们能通过反射被读取到 */ RUNTIME }
详解:
@Document
@Documented注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。
@Inherited
@Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解。@Inherited注解只对那些@Target被定义为ElementType.TYPE的自定义注解起作用。
4 反射获取注解
public class TestAnnotation {
public static void main(String[] args) {
try {
Class clazz = Class.forName("com.htf.aggregate.controller.WorkTaskController"); Method method = clazz.getMethod("createTask", WorkTaskAddUpdateRequest.class); if(method.isAnnotationPresent(OperateLog.class)){
System.out.println("WorkTaskController类上配置了OperateLog注解!"); //获取该元素上指定类型的注解 OperateLog operateLog = method.getAnnotation(OperateLog.class); System.out.println("operateType: " + operateLog.operateType() + ", module: " + operateLog.module() + ", operationDetail: " + operateLog.operationDetail()); }else{
System.out.println("WorkTaskController类上没有配置OperateLog注解!"); } }catch (ClassNotFoundException e) {
throw new RuntimeException(e); } catch (NoSuchMethodException e) {
throw new RuntimeException(e); } } }
解释:
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/111694.html