Kotlin:使用反射设置带注释的 lateinit var

Kotlin: set annotated lateinit var using reflection

假设我尝试构建简单的依赖注入库。它的 Injector class,当在特定的 class 上调用时,应该注入所有用 @Service 注释注释的属性。

例如,给定这个客户:

class ClientA {
    @Service private lateinit var service1: Service1
    @Service private lateinit var service2: Service2
    private lateinit var service3: Service3
}

injector.inject(ClientA()) 的调用应该导致 service1service2 被设置(但不是 service3)。假设 Injector 知道如何构造这些对象。

我的问题是如何编写解析 class' 属性、检查其注释并在 Kotlin 中设置它们的代码?

因为我在 Android,所以我试图通过 Java 反思:

fun inject(client: Any) {
    val clientClass = client::class.java
    val fields = clientClass.declaredFields
    for (field in fields) {
        if (isAnnotatedForInjection(field)) {
            injectField(client, field)
        }
    }
}

private fun isAnnotatedForInjection(field: Field): Boolean {
    val fieldAnnotations = field.annotations
    for (annotation in fieldAnnotations) {
        if (annotation is Service) {
            return true
        }
    }
    return false
}

问题是 fieldAnnotations 是空的。将 ClientA 的代码转换为 Java 我看到以下内容:

public final class ClientA {
   private Service1 service1;
   private Service2 service2;
   private Service3 service3;

   /** @deprecated */
   // $FF: synthetic method
   @Service
   private static void service1$annotations() {
   }

   /** @deprecated */
   // $FF: synthetic method
   @Service
   private static void service2$annotations() {
   }
}

看起来 Kotlin 编译器创建了静态方法来聚合属性的注释。有了这些信息,我可以编写一些丑陋的代码来使用 Java 的反射 API,但必须有更简洁的方法,对吗?

如果要在字段上放置注释,可以使用@field:Service