如何在Kotlin中取消初始化Lateinit [英] How to uninitialize lateinit in Kotlin
问题描述
我有一个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屋!