《Java 注解Annotation的使用》
本篇只是上一面这一篇的Kotlin实现。
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS)
annotation class SerializableJSON()
在Kotlin中定义一个注解时,要使用annotation
关键字。除了定义我们自己的注解之外,我们还可以用JDK提供的注解来为自定义注解添加些元数据,以此来说明自定义注解的用途。
因为我们这个注解是在运行程序的过程中需要使用的,那么我们这个注解的可见性就是在运行时,所以我们可以加上这个注解@Retention(AnnotationRetention.RUNTIME)
因为我们打算把这个注解应用在类上,那么我们可以加上这个注解@Target(AnnotationTarget.TYPE)
,这样之后,系统会检查这个自定义注解是否用在类上了。
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
annotation class JsonField(val key:String = "")
这个地方与java不同的,java是定义 一个方法key()
,而对应的kotlin则变成了一个字段。
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class BeforeSerializable()
data class Student(
@JsonField
val lastName: String,
@JsonField
val firstName: String,
@JsonField("fullName")
var name: String = "",
@JsonField("home")
val address: String,
@JsonField
val age:Int,
val school:String
){
@BeforeSerializable
private fun obtainFullName(){
name = "$lastName ${firstName}@"
}
}
上面提到的注解将会如何被处理,就是现在要讲的。也就是如果只定义注解而没有相应的注解处理实现,那么一切都是空谈。
@SerializableJSON
private fun checkIfSerializable(obj:Any){
if(!obj.javaClass.isAnnotationPresent(SerializableJSON::class.java)){
throw Exception("${obj.javaClass.simpleName} is not annotated with SerializableJSON")
}
}
@BeforeSerializable
的方法,这是做序列化前要做的事 private fun executeInitialFunction(obj:Any){
for (method in obj.javaClass.methods){
if(method.isAnnotationPresent(BeforeSerializable::class.java)){
method.isAccessible = true
method.invoke(obj)
}
}
}
method.isAccessible = true
可以执行对象中的private方法。
private fun getJsonString(obj: Any): String {
val map: MutableMap<String, Any> = mutableMapOf()
for (field in obj.javaClass.declaredFields) {
field.isAccessible = true
if (field.isAnnotationPresent(JsonField::class.java)) {
field.get(obj)?.let { it ->
getKey(field)?.let { it1 ->
map[it1] = it
}
}
}
}
return "{${
map.entries.stream().map {
"\"${it.key}\":${if(it.value is String) "\"${it.value}\"" else it.value}"
}.collect(Collectors.joining(","))
}}"
}
private fun getKey(field: Field): String? {
val jsonField = field.getAnnotation(JsonField::class.java)
return if (jsonField != null) {
if (jsonField.key.isEmpty()) {
field.name
} else {
jsonField.key
}
} else null
}
fun testParseToJson() {
val student = Student(lastName = "Wong", firstName = "ban", address = "GZ", age = 18, school = "110Mid")
val jsonParser = JsonParser()
val actual: String = jsonParser.parseToJson(student)
val expected =
"{\"lastName\":\"Wong\",\"firstName\":\"ban\",\"fullName\":\"Wong ban@\",\"home\":\"GZ\",\"age\":18}"
assertEquals(expected, actual)
}
Demo