Java反射之AnnotatedType接口
上一篇Java反射之获取注解的AnnotatedElement接口介绍了 AnnotatedElement 接口,它是用反射获取注解的顶级接口。其实现类或子接口包括 Class、TypeVariable、Parameter、Package、AccessibleObject、GenericDeclaration 等,这些在前边的文章中已经介绍过。另外,它还有一个重要的接口 AnnotatedType,本篇将介绍它。 1. 再说注解 JDK1.5推出了注解功能,给Java语言带来非常强大的诸多特性。Java注解有几种保留策略:源码、运行时、类,可以在创建注解时通过 @Retention 元注解来指定,它需要引用 RetentionPolicy 中定义的策略: SOURCE: 注解只在源码层面保留,编译后被丢弃 CLASS: 默认的保留策略,注解将由编译器记录在类文件中,但在运行时不需要由 JVM 保留 RUNTIME: 注解不仅保留在类文件,在运行时 JVM 也会保留它,因此可以通过反射获取注解 注解的作用大概可以分为以下几种: 提供编译期特性:Java提供的一些注解,可以进行编译期特性支持,比如 @SuppressWarnings, @Deprecated 和 @Override 等可以提供编译期检查,@FunctionalInterface 标注函数式接口等 生成帮助文档:Java的 @Documented 注解可以用来标记生成 javadoc 时保留类或接口上的注解 运行时获取注解实现特定逻辑:这个是使用最多的场景,使用注解,并通过反射获取注解,来实现自身业务逻辑,大多数框架都使用注解来实现高级特性,比如 Spring 的 @Bean、 @Service 等注解 一句话,有了注解,我们可以方便的按需实现自身业务逻辑。在JDK1.8之前呢,注解所能表示标注的位置有限,JDK1.8又新增了两种标注位置,支持将注解标注在任何类型上。 2. 再说注解标注的位置 还记得 上一篇 介绍注解标注的位置信息吗?文中提到,通过 ElementType 枚举来定义注解可标注的位置信息,其他包括下边两项: ElementType.TYPE_PARAMETER: 标注在类型参数上,比如泛型参数T、E上 ElementType.TYPE_USE: 使用类型,注解可以标注在任何类型变量上 它们都是在JDK1.8时新增的,TYPE_PARAMETER 主要目的在于支持将注解标注在泛型类型的参数上,而 TYPE_USE 范围更广,可以将注解标注在任何Java类型上。也就是说,JDK1.8之前,注解只能标注在特定的位置(类、方法、包、参数、域、构造器、本地变量、注解),不能标注在泛型参数上,JDK1.8之后,可以标注在任何类型上。 使用TYPE_USE就可以省略其他 ElementType 元素吗? 既然 TYPE_USE 可以表示标注在所有类型上,那么是不是就不需要其他 ElementType 元素了呢?肯定不是!TYPE_USE 有其特殊的目的,它表示 “类型使用” 类型,其实就是指任何Java类型,但是它只能用 AnnotatedType 来描述并获取注解信息(见这里)。 ...