- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
您好,当我使用 Kotlin 编写 Android 程序时,我在代码中看到了 lateinit
。 Java 中的等价物是什么?如何将此代码从 Kotlin 更改为 Java?
public class MyTest {
lateinit var subject: TestSubject
}
最佳答案
Kotlin 中的
lateinit
可以让您可以在创建包含它们的类时无法初始化的变量上拥有不可空类型。
使用您的示例,如果您不使用 lateinit
,则必须使 subject
可以为 null,因为它必须使用一个值进行初始化。
public class MyTest {
var subject: TestSubject? = null
}
这将迫使您每次使用它时都进行空值检查,这很丑陋,因此您可以将其标记为 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();
编辑:这与 lateinit
在 Kotlin 中的工作方式非常相似,如果您将示例的字节码反编译为 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 lateinit 对应java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42964397/
我在 init block 中初始化响应但是抛出异常:/为什么? lateinit var response: MutableLiveData> init { response.valu
我想知道如何在 C# 中使用 后期初始化的 类字段和 可为空引用类型 。 想象一下下面的类: public class PdfCreator { private PdfDoc doc; p
我正在尝试使用注释@MockBean 初始化(通过模拟)两个对象 它似乎只有在我调用方法 mock(className) 时才有效,但由于我想在多个方法上使用模拟类,我不想在我的测试方法中重复相同的代
使用数据绑定(bind)、ViewModel、LiveData ( MVVM )。 在我的布局中有一个表单可以添加员工详细信息。 布局:
使用 Retrofit2 和 rxjava2 未在 Recyclerview 中设置 Gson 可转换数据,然后通过其订阅给出错误: UninitializedPropertyAccessExcept
我的 Kotlin Activity 中有 lateinit 属性,这是它的简化版本: class CreateNewListOfQuestions : AppCompatActivity() {
我有一个自定义的线性布局类,当我想创建这个类的实例时,我收到以下错误: lateinit 属性尚未初始化 我正在使用最新版本的 butterknife 库。 以下是我的 Kotlin 类: class
以下两种方法有什么区别或没有区别: 1. private lateinit var binding: ResultProfileBinding override fun onCreate(savedI
所以我想要实现的是稍后在主函数中设置顶级变量,但我不想让它成为一个肯定会破坏 Extension 的 lateinit var可变功能。 例如,此代码不起作用,因为扩展变量不支持 lateinit 修
如果我有一个 lateinit 变量,我可以检查它是否使用 (this::lateInitVar.isInitialized) 初始化,如 https://stackoverflow.com/a/47
关于这个问题已经有几个 QA,但对我来说,他们似乎在谈论不同的事情(大多数情况下是 Android 的 Kotlin + Dagger2),而不是应用我的具体案例。 我通过阅读 this blog p
成员 lateinit 变量初始化可以通过以下方式检查: class MyClass { lateinit var foo: Any ... fun doSomething()
以下 Kotlin 代码有效 val (x, y) = getSomeXYPair() 但是你不能用 lateinit 全局变量来做到这一点 class Foo { private latei
当我运行从 Firebase github 存储库下载的 quickstart-Android Firebase 数据库入门应用程序时,无论我选择(通过对话框)运行 Java 版本还是 Kotlin
您好,当我使用 Kotlin 编写 Android 程序时,我在代码中看到了 lateinit。 Java 中的等价物是什么?如何将此代码从 Kotlin 更改为 Java? public class
我想知道是否有办法检查 lateinit 变量是否已初始化。例如: class Foo() { private lateinit var myFile: File fun bar(pa
我是 Android 的新手,我正在尝试使用 Dagger2 和 MVVM 模式以及 kotlin 创建一个应用程序,但我无法让它运行。 我的应用类代码。 class PruebaDaggerApp:
我在 BreakingNewsFragment 中使用这一行 viewModel = (activity as NewsActivity).viewModel 初始化了 viewModel,但是收到以
我知道有类似的问题,但我只是找不到类似的东西,我一直在学习新的东西来学习,同时将 kotlin 合成转换为 viewvbinding模式,我遇到了这个错误 kotlin.UninitializedPr
我在尝试将环境变量值分配给 lateinit 变量时遇到错误。错误是“原始类型的属性不允许'lateinit'修饰符”。 我的application.properties(读取环境变量) my.pro
我是一名优秀的程序员,十分优秀!