您好,登錄后才能下訂單哦!
Kotlin 的注解類詳解及實(shí)例
注解聲明
注解是將元數(shù)據(jù)附加到代碼的方法。要聲明注解,請將 annotation 修飾符放在類的前面:
annotation class Fancy
注解的附加屬性可以通過用元注解標(biāo)注注解類來指定:
@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) } }
如果需要對類的主構(gòu)造函數(shù)進(jìn)行標(biāo)注,則需要在構(gòu)造函數(shù)聲明中添加 constructor 關(guān)鍵字 ,并將注解添加到其前面:
class Foo @Inject constructor(dependency: MyDependency) { // …… }
你也可以標(biāo)注屬性訪問器:
class Foo { var x: MyDependency? = null @Inject set }
構(gòu)造函數(shù)
注解可以有接受參數(shù)的構(gòu)造函數(shù)。
annotation class Special(val why: String) @Special("example") class Foo {}
允許的參數(shù)類型有:
注解參數(shù)不能有可空類型,因?yàn)?JVM 不支持將 null 作為 注解屬性的值存儲(chǔ)。
如果注解用作另一個(gè)注解的參數(shù),則其名稱不以 @ 字符為前綴:
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"))
如果需要將一個(gè)類指定為注解的參數(shù),請使用 Kotlin 類 (KClass)。Kotlin 編譯器會(huì) 自動(dòng)將其轉(zhuǎn)換為 Java 類,以便 Java 代碼能夠正常看到該注解和參數(shù) 。
import kotlin.reflect.KClass annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any?>) @Ann(String::class, Int::class) class MyClass
Lambda 表達(dá)式
注解也可以用于 lambda 表達(dá)式。它們會(huì)被應(yīng)用于生成 lambda 表達(dá)式體的 invoke() 方法上。這對于像 Quasar這樣的框架很有用, 該框架使用注解進(jìn)行并發(fā)控制。
annotation class Suspendable val f = @Suspendable { Fiber.sleep(10) }
注解使用處目標(biāo)
當(dāng)對屬性或主構(gòu)造函數(shù)參數(shù)進(jìn)行標(biāo)注時(shí),從相應(yīng)的 Kotlin 元素 生成的 Java 元素會(huì)有多個(gè),因此在生成的 Java 字節(jié)碼中該注解有多個(gè)可能位置 。如果要指定精確地指定應(yīng)該如何生成該注解,請使用以下語法:
class Example(@field:Ann val foo, // 標(biāo)注 Java 字段 @get:Ann val bar, // 標(biāo)注 Java getter @param:Ann val quux) // 標(biāo)注 Java 構(gòu)造函數(shù)參數(shù)
可以使用相同的語法來標(biāo)注整個(gè)文件。 要做到這一點(diǎn),把帶有目標(biāo) file 的注解放在 文件的頂層、package 指令之前或者在所有導(dǎo)入之前(如果文件在默認(rèn)包中的話):
@file:JvmName("Foo") package org.jetbrains.demo
如果你對同一目標(biāo)有多個(gè)注解,那么可以這樣來避免目標(biāo)重復(fù)——在目標(biāo)后面添加方括號 并將所有注解放在方括號內(nèi):
class Example { @set:[Inject VisibleForTesting] var collaborator: Collaborator }
支持的使用處目標(biāo)的完整列表為:
要標(biāo)注擴(kuò)展函數(shù)的接收者參數(shù),請使用以下語法:
fun @receiver:Fancy String.myExtension() { }
如果不指定使用處目標(biāo),則根據(jù)正在使用的注解的 @Target 注解來選擇目標(biāo) 。如果有多個(gè)適用的目標(biāo),則使用以下列表中的第一個(gè)適用目標(biāo):
Java 注解
Java 注解與 Kotlin 100% 兼容:
import org.junit.Test import org.junit.Assert.* import org.junit.Rule import org.junit.rules.* class Tests { // 將 @Rule 注解應(yīng)用于屬性 getter @get:Rule val tempFolder = TemporaryFolder() @Test fun simple() { val f = tempFolder.newFile() assertEquals(42, getTheAnswer()) } }
因?yàn)?Java 編寫的注解沒有定義參數(shù)順序,所以不能使用常規(guī)函數(shù)調(diào)用 語法來傳遞參數(shù)。相反,你需要使用命名參數(shù)語法。
// Java public @interface Ann { int intValue(); String stringValue(); } // Kotlin @Ann(intValue = 1, stringValue = "abc") class C
就像在 Java 中一樣,一個(gè)特殊的情況是 value 參數(shù);它的值無需顯式名稱指定。
// Java public @interface AnnWithValue { String value(); } // Kotlin @AnnWithValue("abc") class C
如果 Java 中的 value 參數(shù)具有數(shù)組類型,它會(huì)成為 Kotlin 中的一個(gè) vararg 參數(shù):
// Java public @interface AnnWithArrayValue { String[] value(); } // Kotlin @AnnWithArrayValue("abc", "foo", "bar") class C
對于具有數(shù)組類型的其他參數(shù),你需要顯式使用 arrayOf:
// Java public @interface AnnWithArrayMethod { String[] names(); } // Kotlin @AnnWithArrayMethod(names = arrayOf("abc", "foo", "bar")) class C
注解實(shí)例的值會(huì)作為屬性暴露給 Kotlin 代碼。
// Java public @interface Ann { int value(); } // Kotlin fun foo(ann: Ann) { val i = ann.value }
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。