带着你一步一步在Kotlin使用注解,让你不再害怕注解
来源:互联网 发布:数据背后的惊人差异 编辑:程序博客网 时间:2024/05/14 21:02
背景知识:
Kotlin中有以下四种元注解(用来定义注解的注解):
- @Target:限定注解标记的目标(属性、方法、类、扩展等等)
- @Retention:限定注解是否存储到字节码文件中;在运行时通过反射是否可见(默认情况下以上两个条件均为真)
- @Repeatable:允许在同一个元素上重复使用同一个注解
- @MustBeDocumented:指定该注解是公有 API 的一部分,并且应该包含在生成的 API 文档中显示的类或方法的签名中。
在Kotlin中定义一个注解类,需要使用 annotation 关键字:
@Target(AnnotationTarget.PROPERTY)annotation class Valid
实际操作
说明:此次实例是对Spring框架中的Value注解进行简单的实现。大致的运行过程可以概括成这样:在某个类中为它的属性添加@Value(value="key")注解,在配置文件中为注解中出现的关键字赋予相应的值。最终通过注解解析器将配置文件中的值注入到添加了注解的属性中。
第一步:定义注解
说明:我们所定义的是一个属性层级的注解,并且需要在运行时获取注解的相关信息,注解含有一个String类型的参数。最终注解定义的代码是这样子的:
@Target(AnnotationTarget.PROPERTY)@Retention(AnnotationRetention.RUNTIME) //这一行也可以省略annotation class Value(val value:String)
第二步:对注解进行解析
说明:注解的定义十分的简单,就那么几行代码。但你要想让注解真正的起作用,你还需要对注解进行相应的解析才行。在解析注解的过程中会使用到大量和反射有关的代码,对反射的概念不熟悉的同学,先去看看反射要不然看接下来的这些代码会蛮吃力的。
class AnnotationExpression (val obj:Any){
fun expression(){ val clazz=obj::class clazz.declaredMemberProperties.forEach { prop-> val mutableProp= try{ prop as KMutableProperty<*> }catch (e:Exception){ null } ?: return@forEach mutableProp.annotations.forEach { annotation-> val propClassName=mutableProp.returnType.toString().removePrefix("kotlin.") when(propClassName) { in numtypeSet->mutableProp.setter.call(obj, (readProp(annotation as Value) as kotlin.String).toNum(propClassName)) "String"->mutableProp.setter.call(obj, (readProp(annotation as Value) as kotlin.String)) "Boolean"->mutableProp.setter.call(obj, (readProp(annotation as Value) as kotlin.String).toBoolean()) } } } }
通过KClass获取的KProperty1默认是不能被修改的,意味着你只能获取属性的值,而不能对其进行修改。所以在这里,我们对它进行了以下转换
prop as KMutableProperty<*>
因为可能出现使用该注解注释val变量的情况,在这里还进行了异常捕获,当发生异常时,直接跳过接下来的处理过程。
我们可以看到上面的代码中多次出现了 readProp 函数,在这里这个函数的作用是根据注解的信息,从配置文件中读取相应的数据。
private fun readProp(value:Value): Any? { val prop=Properties() prop.load( AnnotationExpression::class.java.getResource("app.properties").openStream()) return prop.get(value.value)}
# app.propertiesname="feint"age=11money=13.5gender=true
由于直接从property中获取的类型可能会和使用了@Value注解的属性的类型不匹配,因此我们需要根据属性的类型对从配置中获取的类型进行转换。
在这里适配了,布尔型、字符串型以及数字型的数据。由于数字型的类别特别多(Int,Double,Byte等等),便专门为String扩展了一个 toNum 函数,它接受一个String类型的参数,表示类型的名称。具体的代码是下面这样子的:
fun String.toNum(className:String):Any{ val clazz=Class.forName("java.lang.${typeMap[className]}") return clazz.getMethod("parse$className",String::class.java).invoke(null,this)}
这个地方又有一个坑,我本来是想通过反射调用Kotlin的String类中类似toInt、toDouble的方法。可是,运行后竟然提示,Kotlin的内置类型目前对反射的支持还不完善。。。无奈只好使用Java中那些包装类的parse方法。
第三步:使用注解
说明:使用的过程也没啥好说的,直接上代码
class User{ @Value(value = "name") lateinit var name:String @Value(value = "age") var age:Int=0 @Value(value = "money") var money:Double=0.0 @Value(value = "gender") var gender:Boolean=false override fun toString(): String { return "(name:$name; age:$age; money:$money; gender:${if(gender) "man" else "woman"})" }}
fun main(args: Array<String>) { val user=User() AnnotationExpression(user).expression() println(user.toString())}
源码地址(Github):注解练习
欢迎关注Kotlin学习网
- 带着你一步一步在Kotlin使用注解,让你不再害怕注解
- 让你不再害怕指针
- 让你不再害怕指针!!!!
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- 让你不再害怕指针
- MATLAB求解函数的零点+代码演示
- 【2017广西邀请赛】hdu 6182 A Math Problem
- CaoHaha's staff(规律,2017中国大学生程序设计竞赛
- eclipse创建虚拟机失败(JDK安装良好的的情况下)
- Universal Link 前端部署采坑记
- 带着你一步一步在Kotlin使用注解,让你不再害怕注解
- moreitemlistviewdemo
- java EE技术体系——CLF平台API开发注意事项(4)——API生命周期治理简单说明
- 在kubernetes 集群上运行分布式tensorflow训练
- jQueryday03(css 层级选择 过滤选择)
- 阿里云服务器购买的流程和步骤,以及如何领取优ecs服务器惠券
- 强力推荐!那些你不能错过的 GitHub 插件和工具
- android webview cookies使用总结
- 9月5日笔记