Kotlin 注解Annotation实践

先做一个简单的联系, 后续的内容逐步补上.

定义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)
                }
            }
        }
    }
}

代码的含义很容易读懂, 不再啰嗦.
如上, 我们就利用注解完成了类成员变量的初始化.

猜你喜欢

转载自blog.csdn.net/weixin_43662090/article/details/109825233