先做一个简单的联系, 后续的内容逐步补上.
定义Annotion类
@Target(AnnotationTarget.FIELD)
annotation class Car(
val message: String,
val title: String
)
其中annotation class上可以用的注解及含义如下
- @Target, 应用在哪些地方
- @Retention 该注解是否存在编译好的class文件中, 默认为true. (还没有实践, 可能和注解生效的时间有关系, 注解可以在编译时间生效, 也可以在运行时生效)
- @Repeatable 是否可以在单个元素上多次使用该注解. 暂时也没有实践
- @MustBeDocumented 指定该注解是公有 API 的一部分,并且应该包含在生成的 API 文档中显示的类或方法的签名中(还没有实践)
其中, @Target的可以取以下值.
public enum class AnnotationTarget {
/** Class, interface or object, annotation class is also included */
CLASS,
/** Annotation class only */
ANNOTATION_CLASS,
/** Generic type parameter (unsupported yet) */
TYPE_PARAMETER,
/** Property */
PROPERTY,
/** Field, including property's backing field */
FIELD,
/** Local variable */
LOCAL_VARIABLE,
/** Value parameter of a function or a constructor */
VALUE_PARAMETER,
/** Constructor only (primary or secondary) */
CONSTRUCTOR,
/** Function (constructors are not included) */
FUNCTION,
/** Property getter only */
PROPERTY_GETTER,
/** Property setter only */
PROPERTY_SETTER,
/** Type usage */
TYPE,
/** Any expression */
EXPRESSION,
/** File */
FILE,
/** Type alias */
@SinceKotlin("1.1")
TYPEALIAS
}
当然我们这里暂时只实践一下field. 其他的以后再说
Field注解实践
我们定义一个类, 将注解标注在类成员变量上
class AnnotationActivity : BaseActivity<ActivityAnnotationBinding>() {
@Car(message = "car message", title = "car title")
lateinit var machine: Machine
override fun getLayoutId(): Int {
return R.layout.activity_annotation
}
override fun afterActivityCreate() {
CarManager.inject(this) //在这里完成machine类的初始化
binding.content.text = "${
machine.myTitle}\n${
machine.myContent}"
}
}
其中Machine类的定义如下
class Machine {
var myTitle: String? = null
var myContent: String? = null
}
CarManager的定义如下
object CarManager {
fun inject(any: Any) {
val clazz = any::class.java
val fields = clazz.declaredFields
for (field in fields) {
logcat("fieldName:${
field.name}")
logcat("canonicalName:${
clazz.canonicalName}")
logcat("simpleName:${
clazz.simpleName}")
logcat("componentType:${
clazz.componentType}")
if (field.isAnnotationPresent(Car::class.java)) {
val car = field.getAnnotation(Car::class.java)
logcat("fieldType:${
field.type}")
logcat("car:$car")
if (field.type == Machine::class.java) {
field.isAccessible = true
val machine = Machine().apply {
this.myTitle = car!!.title
this.myContent = car.message
}
field.set(any, machine)
}
}
}
}
}
代码的含义很容易读懂, 不再啰嗦.
如上, 我们就利用注解完成了类成员变量的初始化.