定義
注解不能有實(shí)體,編譯器禁止為注解類(lèi)指定類(lèi)主體
使用
annotation class
定義一個(gè)注解類(lèi)語(yǔ)法類(lèi)似于 主構(gòu)造函數(shù)的聲明:
注解類(lèi)的所有參數(shù),必須被聲明為
val
。如下:-
注解類(lèi)的參數(shù)可以指定默認(rèn)值。
annotation class Test(val age: String,val score:Int = 40)
-
注解的調(diào)用與構(gòu)造函數(shù)調(diào)用一樣。 可以使用命名參數(shù)法以及省略掉帶默認(rèn)值的參數(shù)。如下例,使用全名參數(shù)法為 age 指定值,同時(shí)省略了有默認(rèn)值的 score 參數(shù):
@Test(age = "aaa") fun test() = println("test")
注解的實(shí)參只能擁有以下數(shù)據(jù)類(lèi)型:基本數(shù)據(jù)類(lèi)型,字符串,枚舉,類(lèi)引用,其他的注解類(lèi),以及這些類(lèi)的數(shù)組。
注解的 實(shí)參在編譯時(shí)期必須已知。因此注解的實(shí)參必須是常量 —— 變量必須使用
const
修飾。
元注解
使用在注解上的注解被稱為元注解
-
對(duì)注解使用
Target
注解,并將其值設(shè)置為ANNOTATION_CLASS
,即可將該注解聲明為元注解@Target(AnnotationTarget.ANNOTATION_CLASS) annotation class Test(val age: String,val score:Int = 40)
-
AnnotationTarget.PROPERTY 表示應(yīng)用到屬性上,但 java 中無(wú)法使用聲明為 PROPERTY 的注解,必須添加 FIELD 值才行。
@Target(AnnotationTarget.ANNOTATION_CLASS,AnnotationTarget.PROPERTY,AnnotationTarget.FIELD) annotation class Test(val age: String,val score:Int = 40)
使用類(lèi)引用做實(shí)參
注解的實(shí)參可以是類(lèi)引用
將一個(gè)參數(shù)的類(lèi)型指定為 KClass,表示該參數(shù)需要的實(shí)參是一個(gè)類(lèi)的 class 對(duì)象,kt 中通過(guò) 類(lèi)名::class
可以獲取指定類(lèi)的 class 對(duì)象。
@Target(AnnotationTarget.FUNCTION)
annotation class Test(val age: KClass<out Any>, val score: Int = 40)
@Test(age = String::class)
fun test() = println()
KClass 的類(lèi)型使用了協(xié)變,因?yàn)榭梢越邮?String::class。如果不使用協(xié)變,則 age 的實(shí)參只能是 Any::class。
泛型類(lèi)為參數(shù)
注解的形參可以使用泛型。
annotation class CustomSerializer(val serializerClass: KClass<out ValueSerializer<*>>)
注解類(lèi)為實(shí)參
注解的實(shí)參可以是另外的注解。
如下,Test2 以 Test 為形參,因此在使用 Test2 時(shí)需要?jiǎng)?chuàng)建一個(gè) Test 實(shí)例。此處與普通的調(diào)用構(gòu)造函數(shù)類(lèi)似。
annotation class Test(val name:String)
@Target(AnnotationTarget.CLASS)
annotation class Test2(val age:Int,val test:Test)
@Test2(age = 10,test = Test("name"))
class Person()
數(shù)組為實(shí)參
泛型的形參可以是數(shù)組類(lèi)型。為數(shù)組類(lèi)型傳遞實(shí)參時(shí),需使用 arrayOf 函數(shù)。如下,test 注解需要兩個(gè) String 數(shù)組,
annotation class Test(val name: Array<String>, val age: Array<String>)
@Test(["2", "3"], arrayOf("3", "3"))
class Person()
參數(shù)寫(xiě)法
注解的實(shí)參可以是基本數(shù)據(jù)類(lèi)型、字符串、枚舉、類(lèi)引用、注解類(lèi)的數(shù)組。對(duì)于基本數(shù)據(jù)類(lèi)型定義成數(shù)組時(shí),使用使用IntArray 或其他相似的類(lèi);對(duì)于其余的需要使用 Array<String>(修改泛型實(shí)參)
annotation class Test(val name: Array<String>, val age: IntArray)
這是因?yàn)?IntArray 對(duì)應(yīng) java 中的 int[],是基本數(shù)據(jù)類(lèi)型的數(shù)組;如果寫(xiě)成 Array<Int> 其對(duì)應(yīng)的是 Integer[],不是基本數(shù)據(jù)類(lèi)型。
對(duì)于 String 來(lái)說(shuō),StringArray 是一個(gè)單獨(dú)的類(lèi),不是數(shù)組,所以不能用于此處 。而 Array<String> 是 String[],可以使用在注解作為參數(shù)類(lèi)型。