• Kotlin注解


    Annotations | Kotlin (kotlinlang.org)

    是什么?

    附加到代码的元数据。

    声明注解

    声明方式

    在类前添加 annotation修饰符

    annotation class Fancy
    
    • 1

    指定额外属性:

    • @Target: 目标元素类型
    • @Retention: 存储类型
    • @Repeatable:单个元素上是否可以应用多个
    • @MustBeDocumented: 标记注解是公开API的一部分,会被包含到生成的公开的API文档中。
    @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
            AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER,
            AnnotationTarget.EXPRESSION)
    @Retention(AnnotationRetention.SOURCE)
    @MustBeDocumented
    annotation class Fancy
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    构造

    可以添加构造参数

    annotation class Special(val why: String)
    
    @Special("example") class Foo {}
    
    • 1
    • 2
    • 3

    参数类型:

    • Java原始类型对应的类型
    • Strings
    • Classes(Foo::class)
      • 指定类作为参数时,可以使用Kotlin类(KClass),编译器会自动将其转换为Java类
    • Enums
    • 其他注解
      • 注解类型用作参数时,无需使用 @前缀。
    • 上述类型的数组类型

    实例化

    在Java中,注解类型是接口的形式,因此可以实现注解接口并且使用其实例。

    在Kotlin中,可以调用注解

    使用

    一般用法:

    @Fancy class Foo {
        @Fancy fun baz(@Fancy foo: Int): Int {
            return (@Fancy 1)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    主构造函数注解需要添加 constructor 关键字

    class Foo @Inject constructor(dependency: MyDependency) { ... }
    
    • 1

    属性访问器也可以被注解:

    class Foo {
        var x: MyDependency? = null
            @Inject set
    }
    
    • 1
    • 2
    • 3
    • 4

    lambdas 表达式也可以被注解:注解会被应用到lambda表达式生成的 invoke() 方法上

    annotation class Suspendable
    
    val f = @Suspendable { Fiber.sleep(10) }
    
    • 1
    • 2
    • 3

    use-site target 注解

    当注解一个属性或者构造函数参数时,由于该属性可能会生成多个java对应的元素,如属性,get和set方法,所以注解在java字节码中有多个可能的位置,使用如下格式可以精确的指定位置:

    class Example(@field:Ann val foo,    // annotate Java field
                  @get:Ann val bar,      // annotate Java getter
                  @param:Ann val quux)   // annotate Java constructor parameter
    
    • 1
    • 2
    • 3

    添加到整个文件的注解:(在package导入之前)

    @file:JvmName("Foo")
    
    package org.jetbrains.demo
    
    • 1
    • 2
    • 3

    单个元素上多个注解的合并写法:

    class Example {
         @set:[Inject VisibleForTesting]
         var collaborator: Collaborator
    }
    
    • 1
    • 2
    • 3
    • 4

    支持的use-site target:

    • file

    • property (使用此标记的注解目标对java不可见)

    • field

    • get (property getter)

    • set (property setter)

    • receiver (扩展函数的receiver 参数或者属性)

      • 注解扩展函数的receiver的参数用法:

        • fun @receiver:Fancy String.myExtension() { ... }
          
          • 1
    • param (构造函数参数)

    • setparam (属性 setter parameter)

    • delegate (the field storing the delegate instance for a delegated property)

    没有指定target时的默认顺序:

    • param
    • property
    • field

    Java注解

    Java注解百分百兼容Kotlin。

    参数顺序

    由于java注解中的参数顺序是未定义的,所以不能使用正常的函数参数调用格式来传递参数,需要使用命名参数的格式:

    // Java
    public @interface Ann {
        int intValue();
        String stringValue();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // Kotlin
    @Ann(intValue = 1, stringValue = "abc") class C
    
    • 1
    • 2

    value参数省略名称

    Java中, 名为value的参数可以省略名称,kotlin也支持。

    // Java
    public @interface AnnWithValue {
        String value();
    }
    
    // Kotlin
    @AnnWithValue("abc") class C
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    数组作为注解参数

    java中的value注解参数如果是数组类型,那么在kotlin中会作为 vararg 参数

    // Java
    public @interface AnnWithArrayValue {
        String[] value();
    }
    
    • 1
    • 2
    • 3
    • 4
    // Kotlin
    @AnnWithArrayValue("abc", "foo", "bar") class C
    
    • 1
    • 2

    名称不是value的参数则需要使用数组字面量格式,或者使用arrayOf(...)

    // Java
    public @interface AnnWithArrayMethod {
        String[] names();
    }
    
    • 1
    • 2
    • 3
    • 4
    @AnnWithArrayMethod(names = ["abc", "foo", "bar"])
    class C
    
    • 1
    • 2

    访问注解实例的属性

    java注解实例的value在kotlin中表现为属性形式,可通过如下方式来访问

    // Java
    public @interface Ann {
        int value();
    }
    
    • 1
    • 2
    • 3
    • 4
    // Kotlin
    fun foo(ann: Ann) {
        val i = ann.value
    }
    
    • 1
    • 2
    • 3
    • 4

    可重复注解

    Kotlin也拥有java一样的可在一个元素上应用多次的可重复注解。

    声明为可重复注解

    通过 @kotlin.annotation.Repeatable 元注解标记注解即可。被标记的 注解在java及kotlin侧都将是可重复的

    差异

    Java 不支持 containing 注解。

    Kotlin 编译器会自动生成一个预定义名称的containing注解,如:

    @Repeatable
    annotation class Tag(val name: String)
    
    // 编译器自动生成名为 @Tag.Container 的 containing 注解
    
    • 1
    • 2
    • 3
    • 4

    自定义名称:通过应用@kotlin.jvm.JvmRepeatable 元注解并传递一个包含注解作为参数的注解可以自定义containing注解的名称

    @JvmRepeatable(Tags::class)
    annotation class Tag(val name: String)
    
    annotation class Tags(val value: Array<Tag>)
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    vue基础
    SpringCloud 微服务全栈体系(十)
    IIS搭建本地电脑服务器:通过内网穿透技术实现公网访问的步骤指南
    abp中iquery类使用orderBy接口功能报错问题
    HNU数理基础课程总结与反思(高数、线代、概率论、大物)
    6.同步异步、正则表达式
    再谈快速的高斯模糊算法(使用多次均值滤波逼近和扩展的二项式滤波滤波器)及其优化。
    postman断言详解
    bug定位策略
    Q&A 特辑 | 百万员工不上班也能领全勤奖的原因都在这里了!
  • 原文地址:https://blog.csdn.net/mospuito/article/details/125315415