学习这个知识需要有一些反射的基础
内置的常用注解
注解可以从源文件,class文件或在运动时反射的多种方式读取,对应的等级是SOURCE
, CLASS
, RUNTIME
Java中已经为我们提供了一些注解,其中常用的有:
- @Override 表示重载方法
- @Deprecated 表示其修饰的对象不建议使用
- @SuppressWarnings 表示忽略其修饰的对象出现的warning
几个简单的例子
使用@Override
修饰,如果重载的方法名写错的话在编译阶段编译器会报错
1 | public class Basic { |
使用@Deprecated
修饰,则在运行时会给出一个过时warning,比较智能的编辑器也会给出相应的警告
1 | public class Basic { |
使用@SuppressWarnings
修饰,编译器在编译的时候不会显示出一些warning,比较智能的编辑器亦是如此
1 | "unchecked"}) ({ |
自己定义一个注释
自己定义的注释隐含继承了 java.lang.annotation.Annotation
接口,一个例子如下
1 | public AnnotationTest { |
value()
为注释内的成员,可以设置默认值,这里设置为”Hello”,当然,也可以没有成员
在使用的时候如下
1 | "hello") (value = |
当然,如果注释内没有成员的话那么括号就可以不写了,也可以增加注释的成员
1 | public AnnotationTest { |
那么使用的使用就要这样了
1 | public class AnnotationTestClass { |
指定注释生效的阶段
当然,也有可以修饰注释的注释,比如 java.lang.annotation.Retention
,用于标识被修饰注释的生效时期,设定的值有三种,有枚举类 java.lang.annotation.RetentionPolicy
指定,如下
- SOURCE 被编译器忽视 @SuppressWarnings @Override
- CLASS 存储于class档中,但运行时被VM忽略
- RUNTIME 存储于class档中,运行时可有VM读入 @Deprecated
注意,第三个可以使用反射的技术调用其中的值,例子如下
先声明一个自定义的注解
1 | // 表示其在运行阶段有效 |
如果用来修饰方法 methodWithAnno
的话,运行时可以使用反射技术调用到MyAnnotation
中的value值
当然,Method,Class,Constructor都可以调用到,还可以判断是否存在这个注解
- isAnnotationPresent() 判断该注解是否存在
- getAnnotation() 调用这个注解
- getDeclaredAnnotations() 获取所有
RetentionPolicy
为 RUNTIME 的注解
1 | public class Retention { |
指定注解修饰的对象
可以使用 java.lang.annotation.Target
修饰自定义的注解指明其可以修饰的对象,类型有枚举类 java.lang.annotation.ElementType
定义,比较多,可以自行查看其源码,这里举一个例子,使自定义的注解只能修饰类的方法
1 | (ElementType.METHOD) |
如果用它修饰别的对象,比如说类(class)编译器就会报错
学习来源
需翻墙