Spring注入了kotlin中通用接口实现的列表

时间:2018-01-18 11:42:38

标签: spring generics dependency-injection kotlin

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

我正在尝试在常规java类中注入一个特定接口的Spring实现列表,这很简单:

@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中重写接口是否更容易?

2 个答案:

答案 0 :(得分:3)

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

  1. 尝试重构API并注入List<IMyClass<? extends SomeInterface>>
  2. 列表
  3. 使用注入List<IMyClass<*>>但明确地将其强制转换为您需要的内容,即myClassList as List<IMyClass<Any>>
  4. 这里是kotlin的擦除更明确。如果你不知道那里有什么类型 - 我们不能保证你的代码能够正常工作,因为kotlin中存在Nothing这样的类型,其实例不可能存在。

答案 1 :(得分:0)

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

在下面回答我如何以我能想到的最佳方式做到这一点:

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

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

    // ...
}