Kotlin学习笔记5-10 其他-注解

注解

Kotlin官网:Other-Annotations

注解声明

注解用来给代码附加元数据,在类前加annotation关键字声明为注解:

annotation class Fancy

使用元注解定义注解的性质:

  • @Target:定义注解可用的目标类型,例如类、函数、属性、表达式等等;
  • @Retention:定义注解是否存储于编译类文件中,运行时是否可见,默认两者皆为true;
  • @Repeatable:定义是否可在同一元素上多次使用;
  • @MustBeDocumented:定义注解是否是公共API的一部分,必须包含在文档中。
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
        AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class Fancy

使用

@Fancy class Foo {
    @Fancy fun baz(@Fancy foo: Int): Int {
        return (@Fancy 1)
    }
}

如果要给主构造加注解,主构造的constructor关键字就不能省略,将注解加在constructor关键字前:

class Foo @Inject constructor(dependency: MyDependency) {
    // ...
}

属性的访问器也可以加注解:

class Foo {
    var x: MyDependency? = null
        @Inject set
}

构造

注解的构造器可以包含参数:

annotation class Special(val why: String)

@Special("example") class Foo {}

允许的参数类型:

  • Java基本类型对应的类,丽日Int, Long等等;
  • 字符串;
  • 类引用(Foo::class);
  • 枚举;
  • 其他注解;
  • 上述类型的数组。

注解的参数不能是可空类型,JVM不支持将空值存储为注解参数。
当注解作为其他注解的参数时,作为参数的注解不加”@”:

annotation class ReplaceWith(val expression: String)

annotation class Deprecated(
        val message: String,
        val replaceWith: ReplaceWith = ReplaceWith(""))

@Deprecated("This function is deprecated, use === instead", ReplaceWith("this === other"))

如果要使用类对象作为注解参数,使用Kotlin类(KClass)。Kotlin编译器会自动转换为Java类,在Java代码中也可以正常使用:

import kotlin.reflect.KClass

annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any>)

@Ann(String::class, Int::class) class MyClass

Lambda

Lambda也可以使用注解,会作用在lambda表达式目标生成的invoke()方法上:

annotation class Suspendable

val f = @Suspendable { Fiber.sleep(10) }

使用侧目标的注解

一个Kotlin元素可能会生成多个对应的Java元素,添加注解时想指定使用侧目标Java元素:

class Example(@field:Ann val foo,    // annotate Java field
              @get:Ann val bar,      // annotate Java getter
              @param:Ann val quux)   // annotate Java constructor parameter

也可以给Kotlin文件整体加注解,文件的注解写在包声明之前,如果在默认包中没有包声明则写在所有导包之前:

@file:JvmName("Foo")

package org.jetbrains.demo

如果一个目标上有多个注解,无需多次重复,可以写到一个中括号中:

class Example {
     @set:[Inject VisibleForTesting]
     var collaborator: Collaborator
}

所有支持的使用侧目标:

  • file文件;
  • property属性(Java中不可见)
  • get(属性的getter);
  • set(属性的setter);
  • receiver接收者(扩展函数或属性的接收者);
  • param参数(构造器参数);
  • setpara(尚需经setter参数);
  • delegate委托(存储委托属性的委托实例的字段)。

给扩展函数的接收者加注解:

fun @receiver:Fancy String.myExtension() { }

如果没有定义使用侧目标会默认使用@Target注解中的,如果有多个符合,按照以下优先级:

  • param参数;
  • property属性;
  • field字段。

Java注解

Kotlin兼容Java注解:

import org.junit.Test
import org.junit.Assert.*
import org.junit.Rule
import org.junit.rules.*

class Tests {
    // apply @Rule annotation to property getter
    @get:Rule val tempFolder = TemporaryFolder()

    @Test fun simple() {
        val f = tempFolder.newFile()
        assertEquals(42, getTheAnswer())
    }
}

由于Java中多个参数的注解参数顺序是不定的,在Kotlin中使用时要指定参数名:

// Java
public @interface Ann {
    int intValue();
    String stringValue();
}
// Kotlin
@Ann(intValue = 1, stringValue = "abc") class C

Java中的特殊属性value无需声明属性名的特性Kotlin也支持:

// Java
public @interface AnnWithValue {
    String value();
}
// Kotlin
@AnnWithValue("abc") class C

数组参数

Java中数组类型的值,如果为value属性,对应Kotlin中为vararg:

// Java
public @interface AnnWithArrayValue {
    String[] value();
}
// Kotlin
@AnnWithArrayValue("abc", "foo", "bar") class C

其他的Java数组型属性对应Kotlin中的数组,使用arrayOf函数,或从Kotlin1.2后支持数组字面值:

// Java
public @interface AnnWithArrayMethod {
    String[] names();
}
// Kotlin 1.2+:
@AnnWithArrayMethod(names = ["abc", "foo", "bar"]) 
class C

// Older Kotlin versions:
@AnnWithArrayMethod(names = arrayOf("abc", "foo", "bar")) 
class D

获取注解的属性

注解中的属性值在Kotlin中作为属性处理:

// Java
public @interface Ann {
    int value();
}
// Kotlin
fun foo(ann: Ann) {
    val i = ann.value
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值