我正在尝试检查lateinit属性是否已初始化.
在Kotlin 1.2中,我们现在有了这个isInitialized方法.当我在声明lateinit属性的类中执行此操作时,它可以正常工作.但是当我尝试从另一个类调用它时,我得到以下警告:
此时无法访问'lateinit var foo:Bar'的后备字段
我的模型类(比方说Person)是用Java编写的.
其他两个类(比如说Test1和Test2)是用Kotlin编写的
例:
class Test1 {
lateinit var person: Person
fun method() {
if (::person.isInitialized) {
// This works
}
}
}
Run Code Online (Sandbox Code Playgroud)
-
class Test2 {
lateinit var test1: Test1
fun method() {
if (test1::person.isInitialized) {
// Error
}
}
}
Run Code Online (Sandbox Code Playgroud)
有机会让这个工作吗?
我目前的解决方法是在Test1中创建一个isInitialized从person属性返回的方法.
fun isPersonInitialized(): Boolean = ::person.isInitialized
//in Test2:
if (test1.isPersonInitialized()) {
// Works
}
Run Code Online (Sandbox Code Playgroud) 只是好奇:在Kotlin中,我很想得到一些可以通过懒惰来初始化的val,但是有一个参数.那是因为我需要为了初始化它而创建的东西很晚.
具体来说,我希望我有:
private lateinit val controlObj:SomeView
Run Code Online (Sandbox Code Playgroud)
要么:
private val controlObj:SomeView by lazy { view:View->view.findViewById(...)}
Run Code Online (Sandbox Code Playgroud)
然后:
override fun onCreateView(....) {
val view = inflate(....)
controlObj = view.findViewById(...)
Run Code Online (Sandbox Code Playgroud)
或在第二种情况下controlObj.initWith(view)或类似的情况:
return view
Run Code Online (Sandbox Code Playgroud)
我无法使用,by lazy因为by lazy初始化时不会接受外部参数.在这个例子中 - 包含view.
当然我有,lateinit var但如果我能确保它在设置后变为只读,我会在一行中完成它会很好.
是否有一种非常干净的方法来创建只读初始化一次的只读变量,但只有当其他变量出生时?任何init once关键字?在init之后,编译器知道它是不可变的?
我知道这里存在潜在的并发问题,但如果我敢于在init之前访问它,我当然应该被抛出.
在Kotlin,假设,我有课:
class MyKotlinClass {
lateinit var field: String
}
Run Code Online (Sandbox Code Playgroud)
根据文件:
延迟初始化的属性也作为字段公开.该字段的可见性将与lateinit属性设置器的可见性相同.
我可以在java代码中使用myKotlinClass.field或myKotlinClass.getField().我想禁用字段访问,只保留通过getter和setter访问.
我怎样才能实现这一目标并保持延迟修饰?
我在我的Android应用程序中使用Dagger2 for DI,并使用此代码将类注入我的Activity中:
@field:[Inject ApplicationContext]
lateinit var context: Context
Run Code Online (Sandbox Code Playgroud)
但是,lateinitKotlin中的原始类型属性不允许使用修饰符(例如Boolean),我该怎么做呢?
@field:[Inject Named("isDemo")]
lateinit var isDemo: Boolean
Run Code Online (Sandbox Code Playgroud)
当我lateinit从这段代码中删除时,我收到此错误Dagger does not support injection into private fields
android dependency-injection kotlin dagger-2 kotlin-lateinit
我在Android上有以下Kotlin类:
class ThisApplication: Application() {
lateinit var network: INetwork
override fun onCreate() {
super.onCreate()
network = Network()
}
}
Run Code Online (Sandbox Code Playgroud)
现在,任何外部类都可以通过简单地执行以下操作来获取INetwork参考:
application.network
Run Code Online (Sandbox Code Playgroud)
但是,这也使外部类可以覆盖该值:
application.network = myNewNetworkReference
Run Code Online (Sandbox Code Playgroud)
我想避免第二种选择.不幸的是,我无法创建该字段,val因为它的初始化需要在onCreate回调中发生.
我还考虑过将字段设为私有并通过函数公开它,如下所示:
private lateinit var network: INetwork
fun getNetwork() = network
Run Code Online (Sandbox Code Playgroud)
但是,无论谁调用getNetwork()仍然可以为其分配一个新值,如下所示:
application.getNetwork() = myNewNetworkReference
Run Code Online (Sandbox Code Playgroud)
如何使网络字段成为外部类的只读?或者甚至更好,val即使我无法在构造函数中初始化它,有没有办法实现它?
成员 lateinit 变量初始化可以通过以下方式检查:
class MyClass {
lateinit var foo: Any
...
fun doSomething() {
if (::foo.isInitialized) {
// Use foo
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,此语法不适用于本地 lateinit 变量。Lint 报告错误:“尚不支持对变量的引用”。从逻辑上讲,应该有一种方法可以做到这一点,因为 lateinit 变量在未初始化时在内部为 null。
有没有办法检查局部变量是否已初始化?
在我的Activity中,我有一个lateinit名为controllerFragment使用的属性.此属性已初始化Activity.onCreate().我Fragment得到它的参考回到我Activity通过onAttach().在Fragment随后调用myActivity.controller在Fragment.onCreate().
通常controller首先在其中初始化Activity.onCreate(),然后Fragment添加.所以这很好用.
但是当我Activity被杀死时,它会试图重建自己及其碎片.这导致在初始化发生之前Fragment.onCreate()被调用.Activity.onCreate()
这些是我现在看到的选项:
controller之前初始化super.onCreate()(如果可能的话)myActivity.controller到以后的生命周期回调,如onViewCreated()::controller.isInitializedKotlin 1.2中提供的东西这是我最好的选择?
这是一个直截了当的问题,但我找不到答案。lateinit var在 Kotlin 中初始化a 时,有没有办法得到通知?
我知道我可以检查它是否已初始化,this::coolvar.isInitialized但这不一样。
谢谢
我有一个 lateinit var 作为
lateinit var someVariable: SomeVariable
Run Code Online (Sandbox Code Playgroud)
我初始化这个值someVariable = SomeVariable(),并在需要时使用它。
在某个时候,我想将所有内容都设置为默认值并希望“取消初始化” someVariable。我怎样才能做到这一点?
我不是在寻找将其类型更改为nullable对象并设置为空。我需要保持一种Non-Null类型。
我想检查扩展方法中是否初始化了 Lateinit 属性。我想在扩展方法内安全地执行对 Lateinit 属性的简单函数调用。
我可以用this::property.isInitialized。
想要写一些扩展,例如:
fun <T> T?.executeSafety(func: T.() -> (Unit)) { this?.func() }
Run Code Online (Sandbox Code Playgroud)
然后我们可以轻松地在 Lateinit 属性上执行简单的方法。请帮忙解决这个问题
我正在学习Kotlin,阅读lateinit关键字让我怀疑它的用处.考虑以下代码:
var testString: String? = null
lateinit var lateTestString: String
fun print() {
print(testString?.length)
print(lateTestString.length)
}
Run Code Online (Sandbox Code Playgroud)
获取字符串长度的唯一区别是通过使用?.运算符检查它是否为null .使用lateinit快捷方式在访问属性或调用方法时不必添加额外的问号?仅仅通过这个事实,我认为增加那个额外的问号比在访问lateinit一个问题时获得异常更值得.
更多研究表明,这lateinit对于尚未初始化变量的注射和/或单元测试是有益的,但它会是.但是,不值得拥有额外的东西?.而不仅仅是.为了不冒异常风险吗?
为什么我们不能使用lateinit可为空的变量?
lateinit var v: String?
Run Code Online (Sandbox Code Playgroud)
lateinit 可空类型的属性不允许使用修饰符
我想使用这个功能
在示例中最简单的事情对我不起作用:
lateinit val foo = 1
val bar = foo::lateinitVar.isInitialized()
Run Code Online (Sandbox Code Playgroud)
但我得到了
unresolved reference lateinitVar
Run Code Online (Sandbox Code Playgroud)
我在Android-Studio(也安装了Kotlin 1.2.10插件)中通过gradle使用Kotlin 1.2.10
kotlin ×13
kotlin-lateinit ×13
android ×6
java ×2
dagger-2 ×1
field ×1
immutability ×1
readonly ×1