Java注解解析
概述
java注解又叫做java标注,是java的一种注释机制,在jdk5.0引入。其可以作用在类、方法、变量、参数和包上。另外,其可以通过反射来获取注解标注的内容。可以说注解就是实现了Annotation的接口
Java注解的分类
Java注解分类的话,大致可以分为三类,分别是标准注解,元注解与自定义注解。
-
标准注解
标准注解就是java内置的注解,主要有@Override,@Deprecated,@SuppressWarnings,@FunctionalInterface
-
@Override:这个注解的作用主要是检查该注解标注的方法是否是重写方法,如果不是重写方法的话编译会不通过会报错。
-
@Deprecated:这个注解的作用主要是标记该方法可能要废弃了,使用的话会报个警告。
-
@SuppressWarnings:这个注解主要是告诉编译器要忽视一些警告。其常见的参数有:
参数 作用 deprecation 使用了不赞成使用的类或方法的警告 unchecked 执行了未检查的转换时的警告,例如使用集合时没有用泛型来指定集合保存的类型 fallthrough 当switch程序块两个case之间没有break时 path 在类路径,源文件路径中有不存在的路径时的警告 serial 在可序列化的类上缺少serialVersionUID定义时的警告 all 所有的警告 -
@FunctionalInterface:用于指示被修饰的接口是函数式接口,在jdk8被引入
-
注解的定义
日常开发中新建Java类,我们使用class、interface比较多,而注解和它们一样,也是一种类的类型,他是用的修饰符为 @interface。
/**自定义注解*/ @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyTestAnnotation { } /**父类标注自定义注解*/ @MyTestAnnotation public class Father { } /**子类*/ public class Son extends Father { } /**测试子类获取父类自定义注解*/ public class test { public static void main(String[] args){ //获取Son的class对象 Class<Son> sonClass = Son.class; // 获取Son类上的注解MyTestAnnotation可以执行成功 MyTestAnnotation annotation = sonClass.getAnnotation(MyTestAnnotation.class); } }
元注解
元注解顾名思义我们可以理解为注解的注解,它是作用在注解中,方便我们使用注解实现想要的功能。元注解分别有@Retention、 @Target、 @Document、 @Inherited和@Repeatable(JDK1.8加入)五种。
@Retention
Retention英文意思有保留、保持的意思,它表示注解存在阶段是保留在源码(编译期),字节码(类加载)或者运行期(JVM中运行)。在@Retention注解中使用枚举RetentionPolicy来表示注解保留时期
@Retention(RetentionPolicy.SOURCE),注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS), 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.RUNTIME), 注解会在class字节码文件中存在,在运行时可以通过反射获取到
如果我们是自定义注解,则通过前面分析,我们自定义注解如果只存着源码中或者字节码文件中就无法发挥作用,而在运行期间能获取到注解才能实现我们目的,所以自定义注解中肯定是使用 @Retention(RetentionPolicy.RUNTIME)
@Target
-
Target的英文意思是目标,这也很容易理解,使用@Target元注解表示我们的注解作用的范围就比较具体了,可以是类,方法,方法参数变量等,同样也是通过枚举类ElementType表达作用类型
-
@Target(ElementType.TYPE) 作用接口、类、枚举、注解
-
@Target(ElementType.FIELD) 作用属性字段、枚举的常量
-
@Target(ElementType.METHOD) 作用方法
-
@Target(ElementType.PARAMETER) 作用方法参数
-
@Target(ElementType.CONSTRUCTOR) 作用构造函数
-
@Target(ElementType.LOCAL_VARIABLE)作用局部变量
-
@Target(ElementType.ANNOTATION_TYPE)作用于注解(@Retention注解中就使用该属性)
-
@Target(ElementType.PACKAGE) 作用于包
-
@Target(ElementType.TYPE_PARAMETER) 作用于类型泛型,即泛型方法、泛型类、泛型接口 (jdk1.8加入)
-
@Target(ElementType.TYPE_USE) 类型使用.可以用于标注任意类型除了 class (jdk1.8加入)
-
一般比较常用的是ElementType.TYPE类型
注解的属性
-
通过上一小节@Repeatable注解的例子,我们说到注解的属性。注解的属性其实和类中定义的变量有异曲同工之处,只是注解中的变量都是成员变量(属性),并且注解中是没有方法的,只有成员变量,变量名就是使用注解括号中对应的参数名,变量返回值注解括号中对应参数类型。相信这会你应该会对上面的例子有一个更深的认识。而@Repeatable注解中的变量则类型则是对应Annotation(接口)的泛型Class。
/**注解Repeatable源码*/ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Repeatable { /** * Indicates the <em>containing annotation type</em> for the * repeatable annotation type. * @return the containing annotation type */ Class<? extends Annotation> value(); }