Kotlin lateinit记者java
你好,当我使用Kotlin来编程Android我已经看到在代码中的lateinit
。 java中的等价物是什么?我怎么把这个代码从Kotlin改成Java?
public class MyTest { lateinit var subject: TestSubject }
在Kotlin的lateinit
是那里,所以你可以有不可初始化的变量类型的变量,在包含它们的类被创建时不能初始化。
使用你的例子,如果你没有使用lateinit
,你必须使subject
空,因为它必须用值初始化。
public class MyTest { var subject: TestSubject? = null }
这会迫使你每次使用它都lateinit
检查,这很丑,所以你可以把它标记为lateinit
。
在Java中,你并不是真的有这个问题,因为一切都是可以空的,而声明一个未初始化的字段没有什么特别的:
public class JavaTest { TestSubject subject; }
这将subject
初始化为null
,所以它实际上相当于非lateinit
Kotlin示例。
Kotlin的lateinit
版本和Java版本之间唯一真正的区别是当你试图访问Kotlin中的一个未初始化的属性时,你会得到一个更具体的异常,即一个UninitializedPropertyAccessException
,这将使得调试比查找原因更容易通用的NullPointerException
。
如果你真的想要这个稍微不同的行为,你可以把你的Java属性封装在某种包装器中,但是我不认为这样做是值得的。 一个非常基本的(例如不是线程安全的)方法是:
有一个属性的通用包装类:
public class Property<T> { private T value = null; public T get() { if (value == null) throw new UninitializedPropertyAccessException("Property has not been initialized"); return value; } public void set(T value) { if (value == null) throw new IllegalArgumentException("Value can't be null"); this.value = value; } }
在你的类中使用这个包装:
public class JavaTest { Property<TestSubject> subject = new Property<>(); }
然后这个用法会给你未初始化的异常:
JavaTest test = new JavaTest(); test.subject.get();
而这一个将运行良好:
JavaTest test = new JavaTest(); test.subject.set(new TestSubject()); test.subject.get();
编辑:这和Kotlin的lateinit
工作非常相似,如果你将你的例子的字节码反编译成Java,这就是你得到的:
public final class MyTest { @NotNull public TestSubject subject; @NotNull public final TestSubject getSubject() { TestSubject var10000 = this.subject; if(this.subject == null) { Intrinsics.throwUninitializedPropertyAccessException("subject"); } return var10000; } public final void setSubject(@NotNull TestSubject var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.subject = var1; } }
基本上,编译器将检查属性访问的代码放入类本身(+使用一些帮助器方法),而不是使用包装器,这是更有效的。
Java中没有这样的属性来延迟属性的初始化。 但是我认为Kotlin和Java的行为是非常相似的。
这是我的两分钱:
在Kotlin访问一个lateinit属性之前,它已经被初始化抛出一个特殊的异常,清楚地标识被访问的属性以及它没有被初始化的事实。 (参考: https : //kotlinlang.org/docs/reference/properties.html )。
在Java中,也抛出了NullPointerException(NPE),表明被访问的属性是Null。
唯一的区别可能是,NPE是一个运行时异常。
- 如何使用Kotlin反序列化包含DocumentReference的Firestore DocumentSnapshot
- 计算器不工作
- Android Studio执行失败的任务compilefreeDebugKotlin
- Java.lang.ClassNotFoundException:没有找到类Kotlin
- 尝试访问其他活动时应用程序崩溃
- 如何在android中的kotlin读取和写入txt文件
- Firebase AdMob引发IncompatibleClassChangeError
- 在kotlin android项目中使用intellij-markdown
- 在Kotlin Android中使用Parceler时没有虚方法错误