【问题标题】:Spring inject list of generic interface implementations in kotlinkotlin 中的 Spring 注入通用接口实现列表
【发布时间】:2022-01-05 23:54:13
【问题描述】:

免责声明:Kotlin 新手,可能是一个容易解决的问题或被误解的基础知识。

我正在尝试注入一个特定接口的 Spring 实现的列表,在一个常规的 java 类中,这很容易,如下所示:

@Autowired
List<IMyClass> myClassList;

但在 Kotlin 中执行以下操作会给我一个错误

@Autowired
lateinit private var myClassList: List<IMyClass<Any>>

// No beans of '? extends IMyClass<Object>' or 'List<? extends IMyClass<Object>>' types found

这样做:

@Autowired
lateinit private var myClassList: List<IMyClass<*>>

使注入工作,但不允许我使用接口中定义的将通用对象作为输入的函数

// Out-projected type 'IMyClass<*>' prohibits the use of 'public abstract fun myFunction(obj: T!): T! defined in com.path.IMyClass'

那么我应该如何解决这个问题?用一些特定的语法在 Kotlin 中重写接口是否更容易?

【问题讨论】:

  • 这个 java 版本不是类型安全的,因为你只是省略了类型信息。我会对 List bean 的外观感兴趣吗?
  • @s1m0nw1我正在替换带注释的值,列表中的接口只有一个函数,它接受 T,查看它并返回不同的 T 值。
  • 可以添加IMyClass接口的定义吗?不是方法,是标题。
  • @ESala 你的意思是这样吗?接口 IMyClass {

标签: spring generics dependency-injection kotlin


【解决方案1】:

我遇到了类似的情况,正如asm0dey 所回答的那样,铸造是一种我认为对我来说更好的解决方案,但以更清洁的方式进行是一个问题。

只是在下面回答我是如何以我能想到的最佳方式做到的:

@Service
class MyService(_myClassList: List<IMyClass<out Any>>) {

    @Suppress("UNCHECKED_CAST")
    val myClassList: List<IMyClass<Any>> = _myClassList.map { it as IMyClass<Any> }

    // ...
}

【讨论】:

    【解决方案2】:

    您在 Java 中所做的只是使用隐式通配符。所以你有两种方法:

    1. 尝试重构API并注入List&lt;IMyClass&lt;? extends SomeInterface&gt;&gt;列表
    2. 使用注入的List&lt;IMyClass&lt;*&gt;&gt;,但将其显式转换为您需要的东西,即myClassList as List&lt;IMyClass&lt;Any&gt;&gt;

    这里的事情是 kotlin 的擦除更加明确。如果你不知道那里是什么类型——我们不能保证你的代码可以工作,因为在 kotlin 中有 Nothing 这样的类型,它的实例不能存在。

    【讨论】:

      猜你喜欢
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多