注解
注解声明
注解是一种将元数据附加到代码中的方法。声明注解需要在类前面使用 annotation 关键字:
1. annotation class fancy
用法
1. @fancy class Foo {
2. @fancy fun baz(@fancy foo: Int): Int {
3. return (@fancy 1)
4. }
5. }
在多数情形中 @ 标识是可选的。只有在注解表达式或本地声明中才必须:
1. fancy class Foo {
2. fancy fun baz(fancy foo: Int): Int {
3. @fancy fun bar() { ... }
4. return (@fancy 1)
5. }
6. }
如果要给构造函数注解,就需要在构造函数声明时添加 constructor 关键字,并且需要在前面添加注解:
1. class Foo @inject constructor (dependency: MyDependency)
2. //...
也可以注解属性访问者:
1. class Foo {
2. var x: MyDependency?=null
3. @inject set
4. }
构造函数
注解可以有带参数的构造函数。
1. annotation class special(val why: String)
2. special("example") class Foo {}
Lambdas
注解也可以用在 Lambda 中。这将会应用到 lambda 生成的 invoke() 方法。这对 Quasar框架很有用,在这个框架中注解被用来并发控制
1. annotation class Suspendable
2. val f = @Suspendable { Fiber.sleep(10) }
java 注解
java 注解在 kotlin 中是完全兼容的:
1. import org.junit.Test
2. import org.junit.Assert.*
4. class Tests {
5. Test fun simple() {
6. assertEquals(42, getTheAnswer())
7. }
8. }
java 注解也可以通过在导入是重命名实现像修改者那样:
1. import org.junit.Test as test
3. class Tests {
4. test fun simple() {
5. ...
6. }
7. }
因为 java 中注解参数顺序是没定义的,你不能通过传入参数的方法调用普通函数。相反,你需要使用命名参数语法:
1. //Java
2. public @interface Ann {
3. int intValue();
4. String stringValue(0;
5. }
7. //kotlin
8. Ann(intValue = 1, stringValue = "abc") class C
像 java 中那样,值参数是特殊的情形;它的值可以不用明确的名字。
1. public @interface AnnWithValue {
2. String value();
3. }
5. //kotlin
6. AnnWithValue("abc") class C
如果java 中的 value 参数有数组类型,则在 kotlin 中变成 vararg 参数:
1. // Java
2. public @interface AnnWithArrayValue {
3. String[] value();
4. }
5. // Kotlin
6. AnnWithArrayValue("abc", "foo", "bar") class C
如果你需要明确一个类作为一个注解参数,使用 Kotlin 类KClass。Kotlin 编译器会自动把它转为 java 类,因此 java 代码就可以正常看到注解和参数了。
1. import kotlin.reflect.KClass
3. annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any?>)
5. Ann(String::class, Int::class) class MyClass
注解实例的值在 kotlin 代码中是暴露属性。
1. // Java
2. public @interface Ann {
3. int value();
4. }
5. // Kotlin
6. fun foo(ann: Ann) {
7. val i = ann.value
8. }
