这是注释定义:
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class MyAnno(val desc: String, val comment: String) { }
以下是MyAnno
使用的地方:
class MyAnnoUser {
@MyAnno(desc = "name", comment = "name comment")
lateinit var name: String
@MyAnno(desc = "age", comment = "age comment")
var age: Int = 0
@MyAnno(desc = "money", comment = "money comment")
var money: Double = 0.0
@MyAnno(desc = "gender", comment = "gender comment")
var gender: Boolean = false
override fun toString(): String {
return "(name: $name; age: $age; money: $money; gender: ${if (gender) "men" else "women"})"
}
}
这是在MyAnno
中读取值的代码:
class MyAnnoExpression(val obj: Any, val context: Context) {
val numTypeSet = setOf("Int", "Double", "Byte")
fun expression() {
val clazz = obj::class
clazz.declaredMemberProperties.forEach { prop ->
val mutableProp = try {
prop as KMutableProperty<*>
} catch (e: Exception) {
null
} ?: return@forEach
val desc = mutableProp.findAnnotation<MyAnno>()
desc?.let {
val propClassName = mutableProp.returnType.toString().removePrefix("kotlin.")
when (propClassName) {
in numTypeSet -> mutableProp.setter.call(obj, (readProp(it, context) as kotlin.String).toNum(propClassName))
"String" -> mutableProp.setter.call(obj, (readProp(it, context) as kotlin.String))
"Boolean" -> mutableProp.setter.call(obj, (readProp(it, context) as kotlin.String).toBoolean())
}
}
}
}
private fun readProp(value: MyAnno, context: Context): Any? {
val prop = Properties()
val input = context.assets.open("app.properties")
prop.load(InputStreamReader(input, "utf-8"))
return prop.get(value.desc)
}
}
现在调试器向我展示了value
函数中readProp(...)
的以下信息:
@com.demo.basekotlin.MyAnno(comment=age comment, desc=age)
但是当我从desc
阅读value
时我得到了例外:
An exception occurs during Evaluate Expression Action : org.jetbrains.eval4j.VOID_VALUE cannot be cast to org.jetbrains.eval4j.AbstractValue
我的代码中找不到任何错误,是否需要另外的程序设置?
据我了解,您只想查看给定属性的注释值。
首先,让我们声明一个注释。
@Target(PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class PropertyAnnotation(val desc: String)
容器:
class Container {
@PropertyAnnotation("Name")
var name: String? = null
@PropertyAnnotation("Age")
var age: Int = -1
var notAnnotatedProperty: String = "not annotated"
}
最后,代码负责获取所有声明的属性,然后找到一个注释为PropertyAnnotation
的属性,将其强制转换为它,并从中获取值。
fun main() {
val container = Container()
container::class.declaredMemberProperties.forEach { property ->
(property.annotations.find {
it is PropertyAnnotation
} as? PropertyAnnotation)?.let {
println("Property: `$property` is ${it.desc}")
}
}
}
输出:
Property: `var Container.age: kotlin.Int` is Age
Property: `var Container.name: kotlin.String?` is Name
善良的丑陋。但是,让我们使用更多的Kotlin pro-dev功能。
让我们为任何非null类型创建扩展函数,它返回给定类型的所有成员属性:
inline fun <reified T : Any> Any.getMemberProperty(): List<T> {
return this::class.declaredMemberProperties.mapNotNull { prop ->
(prop.annotations.find { ann -> ann is T }) as? T
}
}
现在用法:
fun main() {
val container = Container()
container.getMemberProperty<PropertyAnnotation>().forEach {
println(it.desc)
}
}