Kotlin 注解

作者: Wavky | 来源:发表于2018-06-13 23:38 被阅读0次

    元注解

    @Retention 保留期

    • AnnotationRetention.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。 常用于代码检测。
    • AnnotationRetention.BINARY 注解被编译到二进制文件,但不会被加载到 JVM 中。 反射不可见。
    • AnnotationRetention.RUNTIME 注解被编译到二进制文件,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。默认值。可用于运行时反射获取注解信息。

    @Target 作用域

    定义该注解可使用的领域

    • AnnotationTarget.CLASS 可以给一个类型进行注解,类、接口、对象、甚至注解类本身
    • AnnotationTarget.ANNOTATION_CLASS 可以给一个注解类进行注解
    • AnnotationTarget.TYPE_PARAMETER 泛型参数(暂未支持)
    • AnnotationTarget.VALUE_PARAMETER 方法、构造函数的参数
    • AnnotationTarget.PROPERTY (计算)属性(该注解Java不可见)
    • AnnotationTarget.PROPERTY_GETTER 属性getter方法
    • AnnotationTarget.PROPERTY_SETTER 属性setter方法
    • AnnotationTarget.FIELD 字段变量,包括PROPERTY的备用字段(backing field)
    • AnnotationTarget.LOCAL_VARIABLE 局部变量
    • AnnotationTarget.CONSTRUCTOR 构造函数
    • AnnotationTarget.FUNCTION 方法、函数(不包括构造函数)
    • AnnotationTarget.FILE 文件整体
    • AnnotationTarget.TYPE 泛型支持
    • AnnotationTarget.TYPEALIAS typealias类型
    • AnnotationTarget.EXPRESSION 表达式

    @MustBeDocumented

    将注解中的元素包含到 Javadoc 中去。

    @Repeatable

    该注解允许复数应用到同一目标(通过提供不同注解参数区分)

    AbstractProcessor 注解处理器

    派生该处理器子类,复写以下方法:

    • getSupportedAnnotationTypes 返回该处理器负责的目标注解类
    • getSupportedSourceVersion 返回可使用该处理器的Java版本,一般返回 SourceVersion.latest
    • init 环境初始化
    • process 主要的逻辑实现方法

    ※ 使用 AutoService 将注解处理器注册到META-INF元数据中

    @AutoService(Processor::class)
    class MyProcessor: AbstractProcessor() {
    
        override fun getSupportedAnnotationTypes(): MutableSet<String> {
            return mutableSetOf(MyAnnotation::class.java.name)
        }
    
        override fun getSupportedSourceVersion(): SourceVersion {
            return SourceVersion.latest()
        }
    
        override fun process(set: MutableSet<out TypeElement>,
                             roundEnv: RoundEnvironment): Boolean {
            roundEnv.getElementsAnnotatedWith(GenName::class.java)
                    .forEach {
                        val className = it.simpleName.toString()
                        val pack = processingEnv.elementUtils.getPackageOf(it).toString()
                        // else
                    }
            return true
        }
    }
    

    自定义注解

    定义

    注解支持的参数类型:

    • 基本类型
    • 字符串
    • Kotlin类(KClass)
    • 枚举
    • 其他注解
    • 上述类型的数组
    @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)
        }
    }
    
    // 构造函数
    class Foo @Inject constructor(dependency: MyDependency) {
    }
    
    // 属性setter
    class Foo {
        var x: MyDependency? = null
            @Inject set
    }
    
    // Lambda表达式
    val f = @Suspendable { Fiber.sleep(10) }
    

    指定注解作用域

    在使用注解时,可显式指定该注解的作用范围。

    • file 注解整个文件时指定
    • property (计算)属性(该注解对 Java 不可见)
    • field 字段
    • get 属性 getter
    • set 属性 setter
    • receiver 扩展函数或属性的接收者
    • param 构造函数参数
    • setparam 属性 setter 参数
    • delegate 委托属性存储其委托实例的字段

    对PROPERTY属性或构造函数参数使用注解时,可显式指定其作用域:

    class Example(@field:Ann val foo,    // 标注 Java 字段
                  @get:Ann val bar,      // 标注 Java getter
                  @param:Ann val quux)   // 标注 Java 构造函数参数
    

    对整个文件进行注解:

    @file:JvmName("Foo")
    
    package org.jetbrains.demo
    

    同一目标多重注解时,使用数组式声明:

    class Example {
         @set:[Inject VisibleForTesting]
         var collaborator: Collaborator
    }
    

    不指定作用域时,根据注解定义的Target选择应用目标。当存在多个可应用目标时,适配以下第一个合适的对象:

    1. param
    2. property
    3. field

    参考文档:

    Hello World of Annotation Processing in Kotlin
    Kotlin注解文档

    相关文章

      网友评论

        本文标题:Kotlin 注解

        本文链接:https://www.haomeiwen.com/subject/outeeftx.html