在Kotlin获得Lateinit房产

时间:2018-01-23 08:49:42

标签: kotlin

是否有可能在Kotlin ::class.java属性初始化之前获得lateinit

逻辑上它应该可以工作 - 我正在尝试获取一个不是值的类,但实际上它会因未初始化的属性访问异常而失败。

请注意,我正在尝试获取类的属性是泛型类,其类型是通用参数之一:

abstract class MVIFragment<
        out INTERACTOR : MVIInteractor<UINTERFACE>,
        UINTERFACE : MVIUIInterface,
        MODEL : MVIViewModel
        >
    : Fragment(), MVIUIInterface, KodeinAware {


lateinit var viewModel: MODEL

我需要该类来创建ViewModel

的实例
        viewModel = ViewModelProviders.of(this).get(viewModel::class.java)

当然我做不到:

        viewModel = ViewModelProviders.of(this).get(MODEL::class.java)

任何解决方案?

1 个答案:

答案 0 :(得分:4)

由于类型擦除,在运行时不知道泛型类型。这就是Java / JVM的工作方式,Kotlin并没有尝试神奇地解决它。 (与Scala不同,Scala具有神奇的魔法,除非它没有。)

您必须从静态确定类型的某些上下文传递它,例如

class Container<T : Any>(private val tClass: Class<T>) {
    val t: T = tClass.newInstance()
}

Container(String::class.java)

您可以使用带有具体类型的内联函数来隐藏这种丑陋,

class Container<T : Any>(private val tClass: Class<T>) {
    val t: T = tClass.newInstance()

    companion object {
        inline operator fun <reified T : Any> invoke() = Container(T::class.java)
    }
}

Container<String>()

真的编译成同样的东西。 (如果类型推断可以从上下文中确定它,则可以省略<String>。)

在你的情况下,它不可能在基础(抽象)类中做这个技巧;它必须在具体类型上完成。