当前位置: 首页 > 知识库问答 >
问题:

科特林:使用反射设置带注释的后期 var

松正阳
2023-03-14

想象一下,我尝试构建简单的依赖注入库。它的Injector类,当在特定类上调用时,应该注入所有用@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知道如何构造这些对象。

我的问题是如何编写代码来解析类的属性,检查它们的注释并在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
}

问题是< code>fieldAnnotations为空。将< code>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工作,但一定有更干净的方法,对吗?

共有1个答案

山乐生
2023-03-14

如果要在字段上放置批注,可以使用@field:服务

 类似资料:
  • 如何在使用Kotlin的Spring Boot中正确初始化ConfigurationProperties? 目前我喜欢下面的例子: 但是它看起来很丑陋,实际上不是一个iable,foo是常量ue,应该在启动期间初始化,将来不会改变。

  • 我试图将Kotlin与Butternife一起用于我的Android应用程序。 我还有一个EditText,我希望在更改消息时使用Butternife显示消息: 然而,什么也没发生。我把一个断点放入函数--它甚至没有被执行。 附注:我听说过kotterknife,但我看到了一个纯Butterknife的例子。 我做错了什么?

  • 问题内容: 我创建我的注释 我把它放在测试对象的字段上 现在,我想使用获取所有字段的列表。 但是似乎我的block do操作从未执行过,并且字段没有注释,因为以下代码返回0。 有谁可以帮助我,告诉我我做错了什么? 问题答案: 您需要将注释标记为在运行时可用。将以下内容添加到您的注释代码中。

  • 我想在Quarkus中注入bean一个静态编程语言字段。示例文件看起来像 构造函数参数注入工作正常,但字段仍处于未初始化状态。 控制台输出: 有可能在科特林的Quarkus中使用CDI场注入吗?如果是,需要为注射设置什么才能工作? 我是从uberjar运行应用程序,而不是从本地图像运行。 jar包含生成的类org.example.InjectDemo_Bean包含一个方法的分解版本,该方法不显示任

  • 我创建我的注释 我把它放在测试对象的字段上 现在我想用获取所有字段的列表。 但我的block do操作似乎从未执行过,字段没有注释,因为下面的代码返回0。 有人能帮我,告诉我做错了什么吗?

  • 问题内容: 我正在学习具有C ++和Java背景的Kotlin。我期待下面的打印,不。我知道这对应到。默认实现不比较每个成员,即和吗?如果是这样,它会不会看到字符串值相等(因为再次映射到字符串值)?显然,我在Kotlin中还没有涉及平等与身份相关的问题。 问题答案: 您描述的默认实现仅适用于数据类。不适用于从中继承实现的常规类,只需使对象与自身相等即可。