如何在Kotlin中取消初始化Lateinit [英] How to uninitialize lateinit in Kotlin

查看:564
本文介绍了如何在Kotlin中取消初始化Lateinit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Lateinit变量

I have a lateinit var as

lateinit var someVariable: SomeVariable

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

I initialize this value like someVariable = SomeVariable() and use it whenever I need.

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

At a certain point, I want to set everything to default and want to "uninitialize" someVariable. How can I do that?

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

I am not looking for changing its type to a nullable object and set null. I need to keep it a Non-Null type.

推荐答案

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

I don't think it's possible without some kind of wrapper (or reflection, but about in a moment).

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

In fact, lateinit is design for compatibility with DI frameworks etc. If you know that value can be uninitialized in any moment then you should use nullable type.

那反射的东西呢?实际上,lateinit是一种智能包装程序,它使nullable的值像not nullable一样起作用,而不是抛出NullPointerException来抛出UninitializedPropertyAccessException.在JVM中声明时,lateinit属性是null,因此,让我们再次将其设置为null;)

So, what about that reflection thing? lateinit is in fact a kind of smart wrapper that makes nullable value to act like not nullable, and instead of throwing NullPointerException to throw UninitializedPropertyAccessException. lateinit property at the moment of declaration in JVM is null, so, let's make it null again ;)

所以...

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(并且仅可以通过反射)使该文件再次未初始化.还有一件重要的事情-出于好奇心对待它,而不像您的生产代码中应该做的那样.

So, setting that field to null (and it's possible only via reflection) makes this filed uninitialized again. And one important thing - treat it as a curiosity, not like thing that should be in your production code.

这篇关于如何在Kotlin中取消初始化Lateinit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆