Kotlin注解詳解
注解聲明
注解是將元數(shù)據(jù)附加到代碼的方法。要聲明注解,請將 annotation 修飾符放在類的前面:
annotation class MyAnnotation
注解的附加屬性可以通過用元注解標(biāo)注注解類來指定:
-
@Target指定可以用該注解標(biāo)注的元素的可能的類型(類、函數(shù)、屬性、表達式等); -
@Retention指定該注解是否存儲在編譯后的 class 文件中,以及它在運行時能否通過反射可見 (默認都是 true); -
@Repeatable允許在單個元素上多次使用相同的該注解; -
@MustBeDocumented指定該注解是公有 API 的一部分,并且應(yīng)該包含在生成的 API 文檔中顯示的類或方法的簽名中。
@Target(AnnotationTarget.CLASS,AnnotationTarget.FUNCTION,AnnotationTarget.VALUE_PARAMETER,AnnotationTarget.EXPRESSION,
AnnotationTarget.CONSTRUCTOR,AnnotationTarget.PROPERTY_SETTER,AnnotationTarget.FIELD,AnnotationTarget.PROPERTY_GETTER)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class MyAnnotation
使用
class MyClass {
@MyAnnotation
fun myMethod(@MyAnnotation a: Int): Int {
return (@MyAnnotation 10)
}
}
//對類的主構(gòu)造函數(shù)進行標(biāo)注
class MyClass2 @MyAnnotation constructor(a: Int) {
}
//標(biāo)注屬性訪問器
class MyClass3 {
var a: Int? = null
@MyAnnotation set
}
注解也可以擁有自己的構(gòu)造方法,并且構(gòu)造方法也可以接受參數(shù)
annotation class MyAnnotation2(val str: String)
@MyAnnotation2("hello")
class MyClass4
注解構(gòu)造方法所允許的參數(shù)類型:
- 與Java原生類型所對應(yīng)的類型(Int,Long..)
- 字符串:string
- classes(MyClass::class)
- 枚舉:enums
- 其他的注解
- 上述類型的數(shù)組類型
Kotlin的注解參數(shù)是不允許為空類型的,因為JVM不支持以null的形式存儲注解屬性值的。
如果某個注解被用作其他注解的參數(shù),那么其名字就不需要以@字符開頭
示例
annotation class MyAnnotation3(val str:String,val myAnnotation:MyAnnotation2)
@MyAnnotation3("test", MyAnnotation2("welcome"))
class MyClass5
如果需要將某個class作為注解的參數(shù),那么請使用Kotlin class(KClass),Kotlin編譯器會自動將其轉(zhuǎn)換為Java Class,這樣,Java代碼就可以正常看到注解及參數(shù)了。
示例
annotation class MyAnnotation4(val arg1: KClass<*>, val arg2: KClass<out Any>)
@MyAnnotation4(String::class, Int::class)
class MyClass6
注解使用處目標(biāo)(use-site target)
在對類的屬性或者是主構(gòu)造方法的參數(shù)聲明注解時,會存在多個Java元素都可以通過對應(yīng)的Kotlin元素生成出來,因此,在所生成的Java字節(jié)碼中,就會存在多個可能的位置來生成相應(yīng)的注解。若想要精確指定如何來生成注解,那么可以使用注解的使用處目標(biāo)方式來實現(xiàn)。
示例
class MyClass7(@field:MyAnnotation val arg1: String, //注解 Java field
@get:MyAnnotation val arg2: String, //注解 Java getter
@param:MyAnnotation val arg3: String) //注解 Java構(gòu)造方法參數(shù)
可以使用相同的語法來標(biāo)注整個文件。 要做到這一點,把帶有目標(biāo) file 的注解放在文件的頂層、package 指令之前或者在所有導(dǎo)入之前(如果文件在默認包中的話):
@file:JvmName("MyAnnotation")
package com.leofight.kotlin9
如果你對同一目標(biāo)有多個注解,那么可以這樣來避免目標(biāo)重復(fù)——在目標(biāo)后面添加方括號并將所有注解放在方括號內(nèi):
class Example {
@set:[Inject VisibleForTesting]
var collaborator: Collaborator
}
支持的使用處目標(biāo)的完整列表為:
- file;
- property(具有此目標(biāo)的注解對 Java 不可見);
- field;
- get(屬性 getter);
- set(屬性 setter);
- receiver(擴展函數(shù)或?qū)傩缘慕邮照邊?shù));
- param(構(gòu)造函數(shù)參數(shù));
- setparam(屬性 setter 參數(shù));
- delegate(為委托屬性存儲其委托實例的字段)。