java 注解学习

本贴最后更新于 2352 天前,其中的信息可能已经时移世易

背景

注解(Annontation)是 Java5 中引入的新特征。其用途有:

  • 生成文档:如 @param, @return
  • 配置管理:如 spring 中的注解配置
  • 格式检查:编译时进行格式检查,如 @override

第一个例子

VehicleInfo

VehicleInfo.java

Car

Car.java

Train

Train.java

VehicleUtil

VehicleUtil.java

MainVehicle

MainVehicle.java

原理

注解定义时使用了 @interface,这是一个继承了 java.lang.annotation.Annotation 接口的特殊接口。

VehicleUtil.getTrafficInfo 中的 info.id() 是怎么调用的呢?

如果是通常的类实例调用过程,info 是类实例,id() 是类方法。

在本示例中,info$Proxy1 类的实例,这个 proxy 类是 Java 运行时动态生成的代理类。

代理类的类方法调用都会实现了 java.lang.reflect.InvocationHandler 接口,具体到注解代理类中,类方法的调用实际执行了 sun.reflect.annotation.AnnotationInvocationHandler 类。

id() 类方法的执行过程为:

  1. 调用了 AnnotationInvocationHandler.invoke(Object, Method, Object[]) 方法
  2. memberValues 中,本例的值为 {type=汽车, id=1},找到 id 对应的值 1
  3. 返回 1

所以本质上,注解是一个继承了 Annotation 的特殊接口的内置的特殊接口。

元注解

在自定义注解时,需要用到一些内置的注解。这些内置的注解即为元注解,用来即注解其它的注解。

元注释有 4 个:

Documented

如果有 @Documented 注解,即做为了 public contract 的一部分,可以被工具调用,如 javadoc。

反之,如果没有 @Documented 注解,即不做为 public contract 的一部分,不可以被工具调用。

Retention

注解作用的阶段,其类型为 RetentionPolicy,值为

  • SOURCE: 会被编译器抛弃
  • CLASS: 会编译在 class 文件中,但是不需要 VM 运行时加载。这个为默认值。
  • RUNTIME: 会编译在 class 文件中,同时需要在 VM 运行时加载。

Target

注解作用的范围,即在哪个位置用这个注解是合法的。常见的值为:

  • TYPE: 类,接口,枚举类型
  • FIELD: 变量
  • METHOD: 类
  • PARAMETER: 形式参数
  • CONSTRUCTOR: 构造方法
  • LOCAL_VARIABLE: 局部变量
  • ANNOTATION_TYPE: 注解
  • PACKAGE: 包
  • TYPE_PARAMETER: @Since 1.8, 类型参数
  • TYPE_USE: @Since 1.8, 类型使用
  • MODULE: @Since 9, 模块

Inherited

类型是被继承的。本文不展开解释。

Native

@Since 1.8

常量字段中的值可以被 native 代码使用。本文不展开解释。

Repeatable

@Since 1.8

注解类型是可以重复的。本文不展开解释。

常见的标准注解

  • Override
  • Deprecated
  • SuppressWarnings
  • SafeVarargs: Since 1.7
  • FunctionalInterface: Since 1.8

参考

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...