Android 如何";锁;Kotlin中的静态对象
嗯,我有一种情况,在Android 如何";锁;Kotlin中的静态对象,android,kotlin,Android,Kotlin,嗯,我有一种情况,在a类中,我得到“X数据”。 我想将此“X数据”存储在对象X中一次,然后确保此对象的值不可能更改。(设定一次就忘了它) 我的做法: object X { var attribute1: String var attribute2: String } 显然,由于对象属性是var,它们在将来是可变的。我怎样才能避免这种情况?有没有办法分配值(在某段时间内…),然后锁定对象直到应用程序退出?您可以使用lateinit var attribute1:String告诉编
a类中,我得到“X数据”。
我想将此“X数据”存储在对象X
中一次,然后确保此对象的值不可能更改。(设定一次就忘了它)
我的做法:
object X {
var attribute1: String
var attribute2: String
}
显然,由于对象属性是var
,它们在将来是可变的。我怎样才能避免这种情况?有没有办法分配值(在某段时间内…),然后锁定对象直到应用程序退出?您可以使用lateinit var attribute1:String
告诉编译器,您将在使用前将attribute1
设置为非空值
没有像您所说的那样用lateinit val
来“锁定”值
有更多信息。您可以使用lateinit var attribute1:String
告诉编译器,您将在使用attribute1
之前将其设置为非空值
没有像您所说的那样用lateinit val
来“锁定”值
您将获得更多信息。您可以使用委托属性
class MyProperty<T : Any> {
private var value: T? = null
operator fun getValue(myObject: MyObject, property: KProperty<*>): T =
value ?: throw UninitializedPropertyAccessException()
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) = when (this.value) {
null -> this.value = value
else -> throw IllegalAccessException("Property already initialized")
}
}
在上面的示例中,如果在设置值之前尝试访问myProperty
,则会引发异常,但您可以根据自己的意愿处理该异常(返回默认值?可能为null?)
如果您多次尝试分配该值,也会出现异常,但您可以以不同的方式处理该异常,例如,不再设置该值,以便
MyObject.myProperty = "foo"
MyObject.myProperty = "bar"
println(MyObject.myProperty)
将打印“foo”
您可以使用委托属性
class MyProperty<T : Any> {
private var value: T? = null
operator fun getValue(myObject: MyObject, property: KProperty<*>): T =
value ?: throw UninitializedPropertyAccessException()
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) = when (this.value) {
null -> this.value = value
else -> throw IllegalAccessException("Property already initialized")
}
}
在上面的示例中,如果在设置值之前尝试访问myProperty
,则会引发异常,但您可以根据自己的意愿处理该异常(返回默认值?可能为null?)
如果您多次尝试分配该值,也会出现异常,但您可以以不同的方式处理该异常,例如,不再设置该值,以便
MyObject.myProperty = "foo"
MyObject.myProperty = "bar"
println(MyObject.myProperty)
将打印
“foo”
我建议您将var替换为val,使这些属性成为最终属性
var类似于general变量,在kotlin中称为可变变量,可以多次赋值
val类似于常量变量,在kotlin中称为不可变,只能初始化一次
我建议您将var替换为val,使这些属性成为最终属性 var类似于general变量,在kotlin中称为可变变量,可以多次赋值 val类似于常量变量,在kotlin中称为不可变,只能初始化一次
在kotlin中不能
lateinit
不可变属性,并且lateinit var
不允许自定义设置程序。
因此,我的方法是使用一个backing属性、自定义getter和自定义setter实现lateinit var行为。这与lellomans解决方案非常相似
object X {
private lateinit var backingprop: String
var attribute: String
set(arg) {
if (this::backingprop.isInitialized) throw IllegalAccessException("Property already initialized")
backingprop = arg
}
get() = backingprop
}
在kotlin中不能
lateinit
不可变属性,并且lateinit var
不允许自定义设置程序。
因此,我的方法是使用一个backing属性、自定义getter和自定义setter实现lateinit var行为。这与lellomans解决方案非常相似
object X {
private lateinit var backingprop: String
var attribute: String
set(arg) {
if (this::backingprop.isInitialized) throw IllegalAccessException("Property already initialized")
backingprop = arg
}
get() = backingprop
}
我警告你!但你可以用这样的例子:
object Immutable {
val immutableString: String = mutableStaticString ?: "some default value, just in case"
}
var mutableStaticString: String? = null
class App : Application() {
override fun onCreate() {
super.onCreate()
mutableStaticString = "hello duct tape solutions!"
android.util.Log.d("ductTape", mutableStaticString)
android.util.Log.d("ductTape", Immutable.immutableString)
}
}
我警告你!但你可以用这样的例子:
object Immutable {
val immutableString: String = mutableStaticString ?: "some default value, just in case"
}
var mutableStaticString: String? = null
class App : Application() {
override fun onCreate() {
super.onCreate()
mutableStaticString = "hello duct tape solutions!"
android.util.Log.d("ductTape", mutableStaticString)
android.util.Log.d("ductTape", Immutable.immutableString)
}
}
X会在“X数据”可用之前使用吗?X会在“X数据”可用之前使用吗?此方法的问题在于它是在运行时检查的,而不是在编译时检查的。但是,我认为没有编译时检查方法,除非您使用两个变量-
var
和val
,这两个变量在使用var
时也不会进行编译时检查。您是对的,它是在运行时检查的,但是如果您使用val
,则无法直接在属性上赋值。您可以使用setter,但一次性赋值属性的所有魔力都消失了then@lelloman我想说,对于在初始化之前进行访问,UninitializedPropertyAccessException更可取。谢谢@PaulGeorgPodlech这更合适indeed@lelloman不幸的是,您的解决方案不适用于可为空的类型。关于这个主题有一个线程和一个解决方案。这个方法的问题是它是在运行时检查的,而不是在编译时检查的。但是,我认为没有编译时检查方法,除非您使用两个变量-var
和val
,这两个变量在使用var
时也不会进行编译时检查。您是对的,它是在运行时检查的,但是如果您使用val
,则无法直接在属性上赋值。您可以使用setter,但一次性赋值属性的所有魔力都消失了then@lelloman我想说,对于在初始化之前进行访问,UninitializedPropertyAccessException更可取。谢谢@PaulGeorgPodlech这更合适indeed@lelloman不幸的是,您的解决方案不适用于可为空的类型。有一个关于这个主题的线程和一个解决方案。