Kotlin注解探秘:让代码更清晰

快速上手

Kotlin 复制代码
@Target(  
 AnnotationTarget.CLASS,  
 AnnotationTarget.FUNCTION,  
 AnnotationTarget.VALUE_PARAMETER,  
 AnnotationTarget.EXPRESSION,  
 AnnotationTarget.CONSTRUCTOR  
)
@Retention(AnnotationRetention.SOURCE)
@Repeatable
@MustBeDocumented
annotation class MyAnnotation

@MyAnnotation @MyAnnotaion class Test @MyAnnotation constructor(val name: String) {
    @MyAnnotation fun test(@MyAnnotation num: Int): Int = (@MyAnnotation 1)
}

注解的声明

注解使用关键字annotation来声明,比如快速上手中的例子,使用annotation class MyAnnotation就声明了一个注解,我们可以按照定义的规则将其放在其他元素身上

元注解

下面的注解了解过Java的肯定不陌生,元注解就是可以放在注解上面的注解

  • @Target: 用来指定注解可以应用到哪些元素上,有以下可选项

    • CLASS: 可以应用于类、接口、枚举类
    • ANNOTATION_CLASS: 可以应用于注解
    • TYPE_PARAMETER
    • PROPERTY
    • FIELD
    • LOCAL_VARIABLE
    • VALUE_PARAMETER: 可以应用于字面值
    • CONSTRUCTOR: 可以应用于构造函数
    • FUNCTION: 可以应用于函数
    • PROPERTY_GETTER
    • PROPERTY_SETTER
    • TYPE
    • EXPRESSION: 可以应用于表达式
    • FILE
    • TYPEALIAS
  • @Retention: 用来指定注解的生命周期

    • SOURCE: 仅保存在源代码中
    • BINARY: 保存在字节码文件中,但是运行是无法获取
    • RUNTIME: 保存在字节码文件中,运行时可以获取
  • @Repeatable: 允许此注解可以在单个元素上多次使用

拿上方的代码来简单介绍几个元注解

@Target

可以看一下@Target的源码

Kotlin 复制代码
 * This meta-annotation indicates the kinds of code elements which are possible targets of an annotation.
 *
 * If the target meta-annotation is not present on an annotation declaration, the annotation is applicable to the following elements:
 * [CLASS], [PROPERTY], [FIELD], [LOCAL_VARIABLE], [VALUE_PARAMETER], [CONSTRUCTOR], [FUNCTION], [PROPERTY_GETTER], [PROPERTY_SETTER].
 *
 * @property allowedTargets list of allowed annotation targets
 */
@Target(AnnotationTarget.ANNOTATION_CLASS)
@MustBeDocumented
public annotation class Target(vararg val allowedTargets: AnnotationTarget)

在源码中可以看到,Target注解中要传入的参数为allowedTargets,使用了vararh关键字,可传入多个参数,参数的类型为AnnotationTarget,它是一个枚举类,再进入AnnotationTarget的源码就可以看到它有上方元注解中列出的那些。

在快速上手的示例中我们的@Target中传入了Class FUNCTION VALUE_PARAMETER EXPRESSION CONSTRCTOR,表示此注解可以放在类、接口、枚举、函数、字面值、表达式和构造函数上

@Retention

此注解就是指定它什么时候失效 默认是RUNTIME, 快速上手中是用的SOURCE,表示它仅存在于**「源码」中,在编译成字节码后将会消失,如果指定了BINARY,则可以存在于字节码文件中,但是「运行时无法获取」**,反射无法获取

注解的属性

注解可在主构造参数内传值

Kotlin 复制代码
annotation class MyAnnotation2(val effect: String)

class Test2 {
    @MyAnnotation2("Test")
    fun test() {
        println("Run test")
    }
}

比如上面的例子,可以在主构造函数内传入一个参数,参数支持的类型有以下几种

  • Kotlin中的八种"「基本数据类型」"(Byte, Short, Int, Long, Float, Double, Boolean, Char)
  • **「String」**类型
  • **「引用」**类型(Class)
  • **「枚举」**类型
  • **「注解」**类型
  • 以上类型的**「数组类型」** 需要注意的是,官网中特别说明参数不可以传入可空类型,比如"String?",因为JVM不支持null存储在注解的属性中

注解的作用

如果是熟悉Java的开发者对注解的作用肯定是非常熟悉。 注解可以提供给**「编译器、运行时环境、其他代码库以及框架」提供很多可用信息。 可用作 「标记」,可供第三方技术库、框架识别信息,比如大家熟悉的SpringBoot,很多事情就是通过注解和反射来实现 可用来提供更多的 「上下文信息」**,比如方法的类型参数、返回值类型、错误处理

后面可结合反射来深入理解Kotlin在开发中的用途

相关推荐
传奇开心果编程7 小时前
【Jetpack Compose基础语法学与练】第6课 TextField文本输入,字符串状态与输入交互
学习·前端框架·kotlin·android jetpack
ai2work14 小时前
ch06 Jetpack Compose 入门:状态驱动 UI
kotlin
JMchen1 天前
第 12 篇|项目整合与打包发布 —— 从 Demo 到可安装 APK 的完整收官指南
kotlin·android studio
Android打工仔1 天前
不要在 Data 层随意把 Cold Flow 转换成 Hot Flow
android·架构·kotlin
杉氧2 天前
拒绝重复造轮子:我写了一个生产级的 Kotlin 协程与 Flow 工具库(CoroutineKit)
android·kotlin·workflow
JMchen2 天前
第 9 篇|网络请求基础 —— 从 HttpURLConnection 到 OkHttp
kotlin·android studio
hai_android3 天前
Kotlin Flow combine 源码剖析:一个 Channel 如何优雅合并多条流
android·java·kotlin
敲代码的瓦龙3 天前
Jetpack?ViewModel!!!
android·开发语言·kotlin·android-studio
swithun3 天前
不用 WebView,我用 Kotlin + Compose Multiplatform 重写 Mermaid,并做了 2048 组对拍
android·开源·kotlin
JMchen4 天前
第 8 篇|本地存储技术选型 —— SP 与文件读写
kotlin·android studio