声明并应用注解
注解只能拥有如下类型的参数:基本数据类型、字符串、枚举、类引用、其他的注解类,以及前面这些类型的数组。指定注解实参的语法与 Java 有些微小的差别:
-
要把一个类指定为注解实参,在类名后加上
::class
:@MyAnnotation(MyClass::class)
。 -
要把另一个注解指定为一个实参,去掉注解名称前面的
@
。例如,前面例子中的ReplaceWith
是一个注解,但是你把它指定为Deprecated
注解的实参时没有用@
。 -
要把一个数组指定为一个实参,使用
arrayOf
函数:@RequestMapping(path = arrayOf("/foo", "/bar"))
。如果注解类是在 Java 中声明的,命名为value
的形参按需自动地被转换成可变长度的形参,所以不用arrayOf
函数就可以提供多个实参。
Kotlin 支持的使用点目标的完整列表如下:
-
property
-- Java 的注解不能应用这种使用点目标。 -
field
-- 为属性生成的字段。 -
get
-- 属性的 getter。 -
set
-- 属性的 setter。 -
receiver
-- 扩展函数或者扩展属性的接收者参数。 -
param
-- 构造方法的参数。 -
setparam
-- 属性 setter 的参数。 -
delegate
-- 为委托属性存储委托实例的字段。 -
file
-- 包含在文件中声明的顶层函数和属性的类。
用注解控制 Java API
Kotlin 提供了各种注解来控制 Kotlin 编写的声明如何编译成字节码并暴露给 Java 调用者。其中一些注解代替了 Java 语言中对应的关键字:比如,注解@Volatile
和@Strictfp
直接充当了 Java 的关键字volatile
和strictfp
的替身。其他的注解则是被用来改变 Kotlin 声明对 Java 调用者的可见性:
-
@JvmName
将改变由 Kotlin 生成的 Java 方法或字段的名称。 -
@JvmStatic
能被用在对象声明或者伴生对象的方法上,把它们暴露成 Java 的静态方法 -
@JvmOverloads
,曾在第3.2.2小节出现过,指导 Kotlin 编译器为带默认参数值的函数生成多个重载(函数)。 -
@JvmField
可以应用于一个属性,把这个属性暴露成一个没有访问器的公有 Java 字段。
你可以在这些注解的文档注释和在线文档中关于 Java 互操作的章节里找到更多它们用法的细节。
使用注解定制 JSON 序列化
JKid
:https://github.com/yole/jkid
声明注解
@Target(AnnotationTarget.PROPERTY)
annotation class JsonExclude
对拥有参数的注解来说,在类的主构造方法里声明这些参数:
annotation class JsonName(val name: String)
作为对比,下面是如何在 Java 中声明同样的注解
public @interface JsonName {
String value();
}
使用
@JsonName(name = "first_name")`和`@JsonName("first_name")
元注解
AnnotationTarget.PROPERTY,AnnotationTarget.CLASS, AnnotationTarget.METHOD
@Retention注解
你也许在 Java 中见过另一个重要的元注解:@Retention
。它被用来说明你声明的注解是否会存储到 .class 文件,以及在运行时是否可以通过反射来访问它。Java 默认会在 .class 文件中保留注解但不会让它们在运行时被访问到。而大多数注解确实需要在运行时存在,所以 Kotlin 的默认行为不同:注解拥有RUNTIME
保留期。因此,JKid 中的注解没有显式地指定保留期。
网友评论