【问题标题】:How to uninitialize lateinit in Kotlin如何在 Kotlin 中取消初始化 lateinit
【发布时间】:2019-10-11 06:11:18
【问题描述】:

我有一个 lateinit var

lateinit var someVariable: SomeVariable

我像someVariable = SomeVariable() 一样初始化这个值,并在需要时使用它。

在某个时刻,我想将所有内容设置为默认值并想“取消初始化”someVariable。我怎样才能做到这一点?

希望将其类型更改为 nullable 对象并设置为 null。我需要将其保留为 Non-Null 类型。

【问题讨论】:

  • 我只是想了解您的用例。为什么要再次取消初始化该属性?
  • 您可以使用解决方法并为该字段使用委托重置,如下所示:stackoverflow.com/questions/35752575/…
  • @AshrafPatel 用例是前向应变:我不想处理空值检查。我多次使用此变量,我只是不想检查可空性或将其设置为someVariable!!,即使我知道它不为空。我需要的是非空变量。
  • lateinit var 仅用于首次初始化,适用于您知道变量不可为空但无法在构造函数中初始化它的情况(例如在 android 框架中)。如果您在之后“取消初始化”它,那么拥有lateinit var 是没有意义的。 Kotlin 不允许这种操作。
  • @musooff,所以你想回滚到java处理空值的方式?

标签: kotlin kotlin-lateinit


【解决方案1】:

我认为如果没有某种包装器(或反射,但稍后再说),这是不可能的。

事实上,lateinit 是为了兼容 DI 框架等而设计的。如果您知道该值可以随时取消初始化,那么您应该使用 nullable 类型。

那么,那个反射的东西呢? lateinit 实际上是一种智能包装器,它使nullable 的值表现得像not nullable,而不是抛出NullPointerException 抛出UninitializedPropertyAccessExceptionlateinit 在 JVM 中声明时的属性是 null,所以,让我们再次将其设为 null ;)

所以...

class MyClass {
    lateinit var lateinitObject: Any

    fun test() {
        println("Is initialized: ${::lateinitObject.isInitialized}") // false
        lateinitObject = Unit
        println("Is initialized: ${::lateinitObject.isInitialized}") // true

        resetField(this, "lateinitObject")
        println("Is initialized: ${::lateinitObject.isInitialized}") // false

        lateinitObject // this will throw UninitializedPropertyAccessException
    }
}

fun resetField(target: Any, fieldName: String) {
    val field = target.javaClass.getDeclaredField(fieldName)

    with (field) {
        isAccessible = true
        set(target, null)
    }
}

fun main() {
    MyClass().test()
}

因此,将该字段设置为 null(并且只能通过反射实现)会使该字段再次未初始化。还有一件重要的事情 - 把它当作一种好奇心,而不是你的生产代码中应该存在的东西。

【讨论】:

  • 不错。为什么不能在生产代码中使用?
  • lateinit 有理由只初始化一次。如果需要“取消初始化”变量可为空的类型似乎是一个不错的选择。除了教育之外,在这里这样做没有任何价值。
  • 这是一个很棒的测试lateinit变量的解决方案。它允许开发人员编写测试代码,以保证在执行依赖于变量的测试之前未初始化变量。
猜你喜欢
  • 2020-04-26
  • 2022-12-15
  • 1970-01-01
  • 2020-08-08
  • 2020-04-14
  • 1970-01-01
  • 2022-11-22
  • 2021-10-13
  • 2022-07-05
相关资源
最近更新 更多