1. 注解的用处
- 标记作用,给读者提供一些信息
- 为编译器提供信息:可以被编译器用于错误检查和抑制警告
- 编译和部署时进行处理:通过注解信息生成代码、配置文件等
- 运行时进行处理:一些注解信息可以保留到运行时,通过反射进行获取
2. 注解处理
- 编译期间
编译时指定注解处理器,可以自动生成代码和配置文件。参考Java注解处理器 - 运行时
在运行时通过反射动态获取注解信息
3. 元注解
3.1 @Retention:注解的保留位置
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
3.2 @Target:注解的作用目标
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
Local variable annotations are not retained in class files (or at runtime) regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.
@Target(ElementType.ANNOTATION_TYPE)//注解
- `@Target(ElementType.PACKAGE) ///包
- ElementType.TYPE_PARAMETER
泛型参数 - ElementType.TYPE_USE
以用于标注任意类型(不包括class)
类型注解用来支持在Java的程序中做强类型检查,配合第三方插件工具(如Checker Framework),可以在编译期检测出runtime error(如UnsupportedOperationException、NullPointerException异常),避免异常延续到运行期才发现,从而提高代码质量,这就是类型注解的主要作用。
//TYPE_PARAMETER 标注在类型参数上
class D<@Parameter T> { }
//TYPE_USE则可以用于标注任意类型(不包括class)
//用于父类或者接口
class Image implements @Rectangular Shape { }
//用于构造函数
new @Path String("/usr/bin")
//用于强制转换和instanceof检查,注意这些注解中用于外部工具,它们不会对类型转换或者instanceof的检查行为带来任何影响。
String path=(@Path String)input;
if(input instanceof @Path String)
//用于指定异常
public Person read() throws @Localized IOException.
//用于通配符绑定
List<@ReadOnly ? extends Person>
List<? extends @ReadOnly Person>
@NotNull String.class //非法,不能标注class
import java.lang.@NotNull String //非法,不能标注import
3.3 @Inherited
- 类继承关系中@Inherited的作用
类继承关系中,子类会继承父类使用的注解中被@Inherited修饰的注解 - 接口继承关系中@Inherited的作用
接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被@Inherited修饰 - 类实现接口关系中@Inherited的作用
类实现接口时不会继承任何接口中定义的注解
3.4 @Repeatable
自 Java 8 开始引入,表明注解可以在一个元素上重复使用。
//使用Java8新增@Repeatable原注解
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(FilterPaths.class)//参数指明接收的注解class
public @interface FilterPath {
String value();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface FilterPaths {
FilterPath[] value();
}
//使用案例
@FilterPath("/web/update")
@FilterPath("/web/add")
@FilterPath("/web/delete")
class AA{ }
我们可以简单理解为通过使用@Repeatable后,将使用@FilterPaths注解作为接收同一个类型上重复注解的容器,而每个@FilterPath则负责保存指定的路径串。
3.5 @Documented
表明注解在被应用于元素时,这些元素应该使用 Javadoc 生成文档。默认不使用。
4. 其他内置注解
4.1 @Deprecated
4.2 @Override
4.4 @SuppressWarnings
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
数组的接收值为
deprecation:使用了不赞成使用的类或方法时的警告;
unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型;
fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
path:在类路径、源文件路径等中有不存在的路径时的警告;
serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告;
finally:任何 finally 子句不能正常完成时的警告;
all:关于以上所有情况的警告。
4.4 @SafeVarargs
Java 7 开始引入的。当应用于方法或构造方法中时,假定代码不会在可变参数 (varargs ) 中执行不安全的操作。使用这个注解时,和可变参数相关的 unchecked 警告会被抑制。
4.5 @FunctionalInterface
5. 注解数据类型
- 所有基本类型(int,float,boolean,byte,double,char,long,short)
- String
- Class
- enum
- Annotation
- 上述类型的数组
网友评论