自定义注解、使用反射操作注解

自定义注解

这是一篇前导文,为后面打算写的 Spring Boot 读取不到启动类中的自定义注解做铺垫。

你既然都看到这篇文章了,想必比我都了解什么是注解、注解能用来干嘛。之前都对注解怀着“敬畏”的心态,觉得能自定义注解的人一定很厉害,确实的确如此,我见到过的那些人确实都非常厉害。不过话说回来了,注解也不是什么牛鬼蛇神,**它就是一个标签,只不过是这个标签保存在源代码中,并且能被 annotation API 工具(我把它当做注解解析器)操作。**如果只是定义一个注解,而不去写它的解析器,那的确没什么卵用……

语法和规范

@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Test {
    int value() ;
    int key() default 1;
}

上面就是最常见的注解的定义语法了,它用 @interface 关键字定义,注解中的属性定义不太一样,它用类似方法的形式,这些属性要么有默认值,要么在使用注解时提供这些值,注解处理器其实就是利用反射来取到注解的属性,然后再根据属性值来具体做出相应处理。没什么,不要给自己设限。注解也会被编译成 .class 文件

如果一个注解中没有任何属性,就被称作标记注解(mark annotation)。

根据 Java Language Specification(JLS 9.6),注解的名字不能和类名或者接口名相同,原话如下:
It is a compile-time error if an annotation type has the same simple name as any of its enclosing classes or interfaces. 其实这也可以理解,毕竟都是以 .java 结尾嘛

所有的注解都直接继承自 java.lang.annotation.Annotation(注意这货是个接口),这也不难理解,Class 类中的 getAnnotations() 方法返回的都是 Annotation[] 类型的数组。

元注解

并不想去接受这些概念性质的东西,元注解是一种特殊的注解,它被设计用来解释其他注解何时、何处起作用。说白了就是元注解专门负责新注解的创建,如上述你看到的 @Test 注解一样。

Java 提供了四种元注解:

名称参数
@TargetElementType 类型的数组,指明注解能应用在何处,凡是你能想到的地方(类、方法声明、参数、包甚至是局部变量)都能使用注解,具体在 ElementType 枚举类中有定义
@Retention指明注解在什么级别保存该注解,参数为 RetentionPolicy 枚举类,可选值有 SOURCE(被编译器丢弃)、CLASS(在 class 文件中可用,会被 JVM 丢弃)、RUNTIME(JVM 运行时也保留该注解,可通过反射的方式读取该注解的信息),一般情况下我们都是选择 RUNTIMR,你可以留心一下 Lombok 大多是在 SOURCE 级别
@Documented此注解包含在 Javadoc 中
@Inheried允许子类继承父类中的注解

我们定义自己的注解的时候,需要用这些元注解来指明这个注解可以被用到哪里、在哪个级别起作用。

注解中若定义了名为 value 的元素,并且在应用该注解的时候,此元素是唯一一个需要被赋值的元素,那么此时无需使用 “名-值” 对的这种语法,只需在括号中给出 value 元素所需的值即可。——《Java 编程思想》

注解处理器

上面也说了,光有注解没卵用,注解处理器才会让注解发挥出作用。
未完待续!

参考文章:
[1.] Java注解(三) 自定义注解与提取注解
[2.] 自定义Java注解处理器

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值