2020.7.20
学习目的:了解什么是注解,以及注解的作用,并掌握其使用
①注解的作用:通过注解Annotation来实现标识一个类或一个属性、一个方法、一个参数
②Kotlin的注解完全继承与java
③注解只是一个标识,不会影响类的任何运行
④Kotlin中的注解结构与类很相似
注意:注解类里面定义参数时,只能使用val
Target注解
- 语法结构:
@Target(AnnotationTarget.类型)
annotation class 自定义标签(注解)的名字 - 常用的几种标签类型
AnnotationTarget CLASS: 标识一个类
AnnotationTarget CONSTRUCTOR: 标识构造函数
AnnotationTarget PROPERTY: 标识属性
AnnotationTarget FUNCTION: 标识函数
AnnotationTarget VALUE_PARAMETER: 标识函数的参数
//标识类
@Target(AnnotationTarget.CLASS)
annotation class TableName(val name:String)
//标识构造函数
@Target(AnnotationTarget.CONSTRUCTOR)
annotation class MYCons
//标识属性
@Target(AnnotationTarget.PROPERTY)
annotation class Mypram(val colum_name:String)
//标识函数
@Target(AnnotationTarget.FUNCTION)
annotation class MyFunc
//标识函数参数
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class MyFuncPram
@TableName(name = "PeopleTable") class People @MYCons constructor(@Mypram(colum_name = "age") var age:Int){
@Mypram(colum_name = "firstName") val name:String="jack"
@MYCons constructor(name:String):this(12){}
@MyFunc fun show(@MyFuncPram score:Int){
}
}
- 注解类使用参数(属性)可以与标识的对象形成映射关系,如代码中的"jack"对应的是firstName,对号入座
Retention——标签的生命周期 -
三种标签->主要区别是作用域(生命周期)不同,用来修饰Target标签
AnnotationRetention.RUNTIME
AnnotationRetention.SOURCE
AnnotationRetention.BINARY
作用域.png
通常都会使用AnnotationRetention.RUNTIME
注解实战:从数据库中读取数据模型,并返回对象
import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.primaryConstructor
//模型数据
@Entity class User(
@ColumnInfo var id:Int,
@ColumnInfo var name:String,
@ColumnInfo var icon:String
) {
override fun toString(): String {
return "User(id=$id, name='$name', icon='$icon')"
}
}
class Student
//Table -- 类名
//类注解 属性注解
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class Entity
//属性注解
@Retention//默认是RUNTIME
@Target(AnnotationTarget.PROPERTY)
annotation class ColumnInfo
//模拟数据的查询
fun selectData():Map<String,Map<String,Any>>{
//模拟有两个表User Student
//使用Map封装数据 k-v
val userData = mapOf(
Pair("id",1),
Pair("name","rose"),
Pair("icon","www.baidu.com")
)
val studentData = mapOf(
Pair("sId",1),
Pair("name","小王"),
Pair("address","西南大学")
)
val data = mapOf(
Pair("User",userData),
Pair("Student",studentData)
)
return data
}
fun atuoParseFromTable(clz:KClass<out Any>):Any?{
//先从数据库中读取表对应的数据
val datas=selectData()
//判断传递过来的KClass对象有没有Entity表示
val entity=clz.findAnnotation<Entity>()
if(entity==null){
//传递过来的类没有Entity注解
//不能自动转换
return null
}else{
//可以自动转换
//获取类名 ----表名
val tableName =clz.simpleName
//使用这个表名去数据库中获取这个表对应的数据
val info=datas[tableName]
//创建对象,再将info的数据对应地填充到对象的属性中
//使用默认的主构造函数创建
val con=clz.primaryConstructor
//创建一个数组,保存解析的属性的值
val params= arrayOfNulls<Any>(con?.parameters?.size!!)
//遍历构造函数的参数
con.parameters.forEach {
//获取参数名
val value =info?.get(it.name)
//将这个值保存到数组中
params[it.index]=value
}
//使用构造函数创建对象
return con?.call(*params)
}
}
fun main() {
val obj=atuoParseFromTable(User::class) as User
println(obj.name)
//打印rose
}
demo介绍.png