如何使用Injekt库中泛型的injectLazy()委托?
我有一个下面的类层次结构
interface Presenter abstract class MvpFragment<P: Presenter> : Fragment() { val presenter by injectLazy<P>() // error: Cannot use 'T' as reified type parameter. Use a class instead. }
有没有办法使用带有泛型的injectLazy
委托? 我可以将一个KClass<P>
作为参数传递给MvpFragment
,但我仍然不知道如何使用它来注入一个P
对象。
编译Java代码时,泛型类型参数将被删除。 Kotlin提供了一个功能,内联函数可以保持这个类型的信息一直到程序的运行时间。 这个特性是injectLazy<T>
函数用来确定类型参数的。
在你的情况下,类型参数P
来自类,所以Kotlin编译器无法对其进行表示,这意味着编译为Java字节码时会被擦除。 在删除类型参数后,不能再调用injectLazy<T>
函数,因为类型信息在运行时将丢失。 这就是编译器给你错误的原因。
您将不得不将KClass<P>
对象传递给您的类,并使用它来注入依赖关系,从而对手动类型进行分类。
我终于找到了一个方法来做到这一点。 但是我必须先添加两个新的函数:
fun <T: Any> typeRef(type: KClass<T>) = object : TypeReference<T> { override val type = type.java } fun <T : Any> injectLazy(type: KClass<T>): Lazy<T> { return lazy { Injekt.get(forType = typeRef(type)) } }
现在我可以写:
abstract class MvpFragment<P : Presenter>(presenterClass: KClass<P>) : Fragment() { protected val presenter by injectLazy(type = presenterClass) }