在Kotlin中使用Kotlin/java注解及注意事項


一、聲明注解

Kotlin聲明注解的方式與Java略有不同,只需要在class前使用annotation修飾。

annotation class Foo

同Java一樣,可以通過元注解來標記自定義的注解

@Target(AnnotationTarget.PROPERTY)
annotation class Foo

1. 元注解@Target

AnnotationTarget枚舉了所有Kotlin注解可應用到的目標

2. 元注解@Retention

@Retention元注解用來表示你聲明的注解是否會保存到.class文件,以及運行時是否可通過反射來訪問他。
與Java不同,Kotlin注解默認擁有RUNTIME保留期

@Target(AnnotationTarget.PROPERTY)
annotation class Foo

等價於

@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME) // 默認為RUNTIME,可以省略
annotation class Foo

二、使用注解

Kotlin中的注解使用和Java沒有太大的區別,需要注意的是:Kotlin中的類的屬性對應Java中類的多個元素

class A() {
    var name: String? = null
}

等價於java

public class A {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

所以,在使用Kotlin注解時,通過@目標:注解的語法,可以明確指定注解的目標,來自官網的例子

@Target(
    AnnotationTarget.PROPERTY,
    AnnotationTarget.FUNCTION,
    AnnotationTarget.FIELD,
    AnnotationTarget.VALUE_PARAMETER,
    AnnotationTarget.PROPERTY_GETTER
)
annotation class Ann

class Example(
    @field:Ann val foo: String,    // 注解 Java類的字段
    @get:Ann val bar: String,      // 注解 Java getter
    @param:Ann val quux: String    // 注解 Java 構造函數的參數
)

所以使用Java注解,在屬性上對應的目標自然是field

三、通過反射獲得注解信息

在Kotlin中通過反射獲取java信息十分方便,但需要注意,作用在不同目標的注解獲取方式有差異
要使用反射,首先需要引入kotlin-reflect: https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-reflect

    println(Example::foo.annotations)// 獲取 @property: 修飾的注解
    println(Example::foo.findAnnotation<Ann>())// 獲取 @property: 修飾的注解

    println(Example::foo.getter.annotations) // 獲取 @get: 修飾的注解
    println(Example::foo.getter.findAnnotation<Ann>())// 獲取 @get: 修飾的注解

    println(Example::foo.javaField?.annotations) // java方式獲取注解信息,獲取 @field: 修飾的注解以及原生java注解
    println(Example::foo.javaField?.getAnnotation(Ann::class.java))// java方式獲取注解信息,獲取 @field: 修飾的注解以及原生java注解
    // 以此類推......

Kotlin中的findAnnotation方法利用inline函數及reified,可以通過指定泛型的類型來獲取對應注解,十分方便,我們也可以自己實現一個獲取@field:注解的findFieldAnnotation方法

inline fun <reified T : Annotation> KProperty<*>. findFieldAnnotation(): T? {
    return javaField?.getAnnotation(T::class.java)
}

要注意Kotlin反射在首次使用時有性能問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM