Kotlin 的注解類詳解及實(shí)例
Kotlin 的注解類詳解及實(shí)例
注解聲明
注解是將元數(shù)據(jù)附加到代碼的方法。要聲明注解,請(qǐng)將 annotation 修飾符放在類的前面:
annotation class Fancy
注解的附加屬性可以通過用元注解標(biāo)注注解類來指定:
- @Target 指定可以用 該注解標(biāo)注的元素的可能的類型(類、函數(shù)、屬性、表達(dá)式等);
- @Retention 指定該注解是否 存儲(chǔ)在編譯后的 class 文件中,以及它在運(yùn)行時(shí)能否通過反射可見 (默認(rèn)都是 true);
- @Repeatable 允許 在單個(gè)元素上多次使用相同的該注解;
- @MustBeDocumented 指定 該注解是公有 API 的一部分,并且應(yīng)該包含在 生成的 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)
}
}
如果需要對(duì)類的主構(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ù)類型有:
- 對(duì)應(yīng)于 Java 原生類型的類型(Int、 Long等);
- 字符串;
- 類(Foo::class);
- 枚舉;
- 其他注解;
- 上面已列類型的數(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ù),請(qǐng)使用 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() 方法上。這對(duì)于像 Quasar這樣的框架很有用, 該框架使用注解進(jìn)行并發(fā)控制。
annotation class Suspendable
val f = @Suspendable { Fiber.sleep(10) }
注解使用處目標(biāo)
當(dāng)對(duì)屬性或主構(gòu)造函數(shù)參數(shù)進(jìn)行標(biāo)注時(shí),從相應(yīng)的 Kotlin 元素 生成的 Java 元素會(huì)有多個(gè),因此在生成的 Java 字節(jié)碼中該注解有多個(gè)可能位置 。如果要指定精確地指定應(yīng)該如何生成該注解,請(qǐng)使用以下語(yǔ)法:
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ù)
可以使用相同的語(yǔ)法來標(biāo)注整個(gè)文件。 要做到這一點(diǎn),把帶有目標(biāo) file 的注解放在 文件的頂層、package 指令之前或者在所有導(dǎo)入之前(如果文件在默認(rèn)包中的話):
@file:JvmName("Foo")
package org.jetbrains.demo
如果你對(duì)同一目標(biāo)有多個(gè)注解,那么可以這樣來避免目標(biāo)重復(fù)——在目標(biāo)后面添加方括號(hào) 并將所有注解放在方括號(hào)內(nèi):
class Example {
@set:[Inject VisibleForTesting]
var collaborator: Collaborator
}
支持的使用處目標(biāo)的完整列表為:
- file
- property(具有此目標(biāo)的注解對(duì) Java 不可見)
- field
- get(屬性 getter)
- set(屬性 setter)
- receiver(擴(kuò)展函數(shù)或?qū)傩缘慕邮照邊?shù))
- param(構(gòu)造函數(shù)參數(shù))
- setparam(屬性 setter 參數(shù))
- delegate(為委托屬性存儲(chǔ)其委托實(shí)例的字段)
要標(biāo)注擴(kuò)展函數(shù)的接收者參數(shù),請(qǐng)使用以下語(yǔ)法:
fun @receiver:Fancy String.myExtension() { }
如果不指定使用處目標(biāo),則根據(jù)正在使用的注解的 @Target 注解來選擇目標(biāo) 。如果有多個(gè)適用的目標(biāo),則使用以下列表中的第一個(gè)適用目標(biāo):
- param
- property
- field
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)用 語(yǔ)法來傳遞參數(shù)。相反,你需要使用命名參數(shù)語(yǔ)法。
// Java
public @interface Ann {
int intValue();
String stringValue();
}
// Kotlin
@Ann(intValue = 1, stringValue = "abc") class C
就像在 Java 中一樣,一個(gè)特殊的情況是 value 參數(shù);它的值無(wú)需顯式名稱指定。
// 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
對(duì)于具有數(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
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Java語(yǔ)法基礎(chǔ)之循環(huán)結(jié)構(gòu)語(yǔ)句詳解
這篇文章主要為大家詳細(xì)介紹了Java語(yǔ)法基礎(chǔ)之循環(huán)結(jié)構(gòu)語(yǔ)句,感興趣的小伙伴們可以參考一下2016-09-09
Java零基礎(chǔ)也看得懂的單例模式與final及抽象類和接口詳解
本文主要講了單例模式中的餓漢式和懶漢式的區(qū)別,final的使用,抽象類的介紹以及接口的具體內(nèi)容,感興趣的朋友來看看吧2022-05-05
在非spring環(huán)境中調(diào)用service中的方法
非Spring環(huán)境指的是不使用Spring框架來管理和配置應(yīng)用程序的運(yùn)行時(shí)環(huán)境,本文將給大家介紹如何在非spring環(huán)境中調(diào)用service中的方法,文中有詳細(xì)實(shí)現(xiàn)步驟,需要的朋友可以參考下2024-03-03
ActiveMQ基于zookeeper的主從(levelDB Master/Slave)搭建
這篇文章主要介紹了ActiveMQ基于zookeeper的主從levelDB Master/Slave搭建,以及Spring-boot下的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
java接口返回參數(shù)按照請(qǐng)求參數(shù)進(jìn)行排序方式
這篇文章主要介紹了java接口返回參數(shù)按照請(qǐng)求參數(shù)進(jìn)行排序方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java?Excel?Poi字體顏色自定義設(shè)置代碼
最近項(xiàng)目使用POI按模板導(dǎo)出Excel,需要設(shè)置單元格的字體為紅色,下面這篇文章主要給大家介紹了關(guān)于Java?Excel?Poi字體顏色自定義設(shè)置的相關(guān)資料,需要的朋友可以參考下2024-01-01
關(guān)于java String中intern的深入講解
這篇文章主要給大家介紹了關(guān)于java String中intern的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
hibernate 命名查詢?nèi)绾螌?shí)現(xiàn)
Hibernate允許在映射文件中定義字符串形式的查詢語(yǔ)句,這種查詢方式成為命名查詢,需要的朋友可以參考下2012-11-11
Mybatis操作數(shù)據(jù)時(shí)出現(xiàn):java.sql.SQLSyntaxErrorException:?Unknown?c
這篇文章主要介紹了Mybatis操作數(shù)據(jù)時(shí)出現(xiàn):java.sql.SQLSyntaxErrorException:?Unknown?column?'XXX'?in?'field?list',需要的朋友可以參考下2023-04-04

