我想知道是否有方法检查lateinit变量是否已初始化。例如:
class Foo() {
private lateinit var myFile: File
fun bar(path: String?) {
path?.let { myFile = File(it) }
}
fun bar2() {
myFile.whateverMethod()
// May crash since I don't know whether myFile has been initialized
}
}
Kotlin 1.2中有一个lateinit改进,允许直接检查lateinit变量的初始化状态:
lateinit var file: File
if (this::file.isInitialized) { ... }
请参阅JetBrains博客上的公告或KEEP提案。
更新:Kotlin 1.2已经发布。您可以在这里找到lateinit增强功能:
检查lateinit变量是否已初始化Lateinit顶级财产和局部变量
如果在一个类中有一个lateinit属性,并且需要检查它是否是从另一个类初始化的
if(foo::file.isInitialized) // this wouldn't work
我找到的解决方法是创建一个函数来检查属性是否已初始化,然后可以从任何其他类调用该函数。
例子:
class Foo() {
private lateinit var myFile: File
fun isFileInitialised() = ::file.isInitialized
}
// in another class
class Bar() {
val foo = Foo()
if(foo.isFileInitialised()) // this should work
}
kotlin.UninitializedPropertyAccessException: lateinit property clientKeypair has not been initialized
字节码说。。。等等。。
public final static synthetic access$getClientKeypair$p(Lcom/takharsh/ecdh/MainActivity;)Ljava/security/KeyPair;
`L0
LINENUMBER 11 L0
ALOAD 0
GETFIELD com/takharsh/ecdh/MainActivity.clientKeypair : Ljava/security/KeyPair;
DUP
IFNONNULL L1
LDC "clientKeypair"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException (Ljava/lang/String;)V
L1
ARETURN
L2级本地变量$this Lcom/takharact/edch/MainActivity;10升20最大堆栈=2最大局部值=1
Kotlin为同一实例创建一个额外的本地变量,并检查它是否为null,如果为null,则抛出“throwUninitializedPropertyAccessException”,否则返回本地对象。以上字节码在此解释解决方案从kotlin 1.2开始,它允许检查lateinit var是否已初始化或未使用.isInitized
您可以通过以下方式轻松实现:
::variableName.isInitialized
or
this::variableName.isInitialized
但如果您在侦听器或内部类中,请执行以下操作:
this@OuterClassName::variableName.isInitialized
注意:如果您在声明变量的同一文件(同一类或内部类)中编写上述语句,则它们可以正常工作,但如果您想检查其他类(可以是超类或实例化的任何其他类)的变量,则无法正常工作,例如:
class Test {
lateinit var str:String
}
检查str是否已初始化:
我们在这里做的是:检查Test2类中Test类的字段str的isInitialized。我们得到一个错误,var的支持字段此时不可访问。检查已提出的有关此问题。