Kotlin 注解

Kotlin 注解

概述

Kotln的注解继承自Java,因此Kotlin完全兼容Java的注解,注解就是为了给代码提供元数据。合理使用注解可以提高编码效率,带来性能的提升。

Java注解总结

元注解

Kotlin 常见的元注解有四个:

  • @Target,这个注解是指定了被修饰的注解都可以用在什么地方,也就是目标;
  • @Retention,这个注解是指定了被修饰的注解是不是编译后可见、是不是运行时可见,也就是保留位置;
  • @Repeatable,这个注解是允许我们在同一个地方,多次使用相同的被修饰的注解,使用场景比较少;
  • @MustBeDocumented,指定被修饰的注解应该包含在生成的 API 文档中显示,这个注解一般用于 SDK 当中。

@Target元注解

public enum class AnnotationTarget {
    //用于类、接口、object对象表达式、注解类
    CLASS, 
    //用于给注解添加注解
    ANNOTATION_CLASS, 
    //用于对象属性
    PROPERTY, 
    //作用于字段
    FIELD, 
    //局部变量
    LOCAL_VARIABLE, 
    //函数或构造函数的参数
    VALUE_PARAMETER, 
    //作用于构造函数
    CONSTRUCTOR, 
    //作用于函数
    FUNCTION, 
    //属性的getter函数
    PROPERTY_GETTER, 
    //属性的setter函数
    PROPERTY_SETTER, 
    //作用于类、接口、枚举
    TYPE, 
    //用于对象表达式
    EXPRESSION,
    //用于File对象
    FILE, 
}

@Retention元注解

public enum class AnnotationRetention {
    //只保留在源码,编译后不可见
    SOURCE, 
    //编译后可见,保留在字节码中,运行时不可见
    BINARY, 
    //编译后可见,运行时可见,可以通过反射获取信息
    RUNTIME 
}

@Deprecated废弃

  • @Deprecated 只能作用于这些地方:类、 函数、 属性、注解类、构造器、属性 getter、属性 setter、类型别名。
  • @Deprecated 这个类当中还包含了几个成员:
    • message 代表了废弃的提示信息;
    • replaceWith 代表了应该用什么来替代废弃的部分;
    • level 代表警告的程度,分别是 WARNING、ERROR、HIDDEN。

注解的使用

方式一:

@Deprecated(
    message = "请使用CalculatorV2类",
    replaceWith = ReplaceWith("CalculatorV2"),
    level = DeprecationLevel.ERROR
)
class Calculator {
    fun add(a: Int, b: Int) = a - b
}

class CalculatorV2 {
    fun add(a: Int, b: Int) = a + b
}

方式二:

@Target(
    AnnotationTarget.CLASS,
    AnnotationTarget.FUNCTION,
    AnnotationTarget.FUNCTION,
    AnnotationTarget.VALUE_PARAMETER,
    AnnotationTarget.EXPRESSION
)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
@Repeatable
annotation class MyAnnotation()
@MyAnnotation
@MyAnnotation
class User {

    @MyAnnotation
    fun fly(@MyAnnotation desc: String) {
    }
}

自定义注解

声明注解

@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Label(val value: String)
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Formatter(
    val format: String = "yyyy-MM-dd HH:mm:ss",
    val timezone: String = "GMT"
)

使用注解

data class User(
    @Label("姓名") private var name: String,
    @Label("生日") @Formatter(format = "yyyy/MM/dd") private var birthday: Date,
    @Label("今日") @Formatter private var today: Date
)

解析注解

fun processAnnotation(obj: Any): String {
    val kClass = obj::class //获取Kotlin字节码对象
    val builder = StringBuilder()

    //遍历所有属性
    for (memberProperty in kClass.memberProperties) {
        //开放权限
        memberProperty.isAccessible = true

        //获取属性值
        var value = memberProperty.call(obj)

        //判断是否有Label注解
        if (memberProperty.hasAnnotation<Label>()) {

            //获取Label注解
            val label: Label? = memberProperty.findAnnotation<Label>()
            label?.let {
                val name = it.value //获取Label注解的value值

                //判断是否有Formatter注解
                if (memberProperty.returnType.classifier == Date::class && memberProperty.hasAnnotation<Formatter>()) {
                    //获取Formatter注解
                    val formatter: Formatter? = memberProperty.findAnnotation<Formatter>()
                    formatter?.let { f ->
                                    val format = f.format //获取Formatter注解的format值
                                    val timezone = f.timezone //获取Formatter注解的timezone值
                                    val simpleDateFormat = SimpleDateFormat(format)
                                    simpleDateFormat.timeZone = TimeZone.getTimeZone(timezone)
                                    value = simpleDateFormat.format(value)
                                   }
                }

                builder.append("$name: $value \n")
            }
        }
    }
    return builder.toString()
}
fun main() {
    val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    val user = User("小明", sdf.parse("2008-8-8 1:2:3"), Date())
    val result = processAnnotation(user)
    println(result)
}

//生日: 2008/08/07 
//姓名: 小明 
//今日: 2021-12-20 07:56:51
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值