num
should be nullable when set, but what it returns should always be non-nullable (have a default value).
class Test {
var num: Int? = null
get() = field ?: 5 // default value if null
}
The following does not compile even though the returned value is always non-null which makes sense to me, because the type is not inferred but taken from the backing field:
val a: Int = Test().num
Type mismatch: inferred type is Int? but Int was expected
The question is how can I change the return type of that getter to be non-nullable? If I do so, the compiler says:
Getter return type must be equal to the type of the property, ie 'Int?'
I know that I could solve it with another property numNotNullable
(without a backing field).
class Test {
var num: Int? = null
get() = field ?: 5 // default value if null
val numNotNullable: Int
get() = num ?: 5
}
val c: Int = Test().numNotNullable
But this is not what I want. Is there another way?
var num: Int? = null
This is your property signature. It doesn't matter, if you internally ensure that no null
value is returned. The signature says, that the value is nullable.
This implicates:
null
to this field null
Your Solution with a second property is good.
You of course can replace the property with plain old java bean, but I wouldn't advise that, because than you have to access the prop with getNumb
and setNum
.
class Test {
private var num: Int = 5
fun setNum(num: Int?) {
this.num = num ?: 5
}
fun getNum() = num
}
I don't believe this is possible in Kotlin. You can't override the type of the the property for get/set. So if your property is an Int?
you're going to have to return an Int?
and check if it is null
when you use it.
There's technically a feature request for what you're looking for, but it's been years since it was made.
You can achive this using delegated properties
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class LazyVar<T : Any>(private var initializer: () -> T) : ReadWriteProperty<Any?, T> {
private var value: T? = null
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
if (value == null) {
value = initializer()
print(value)
}
return value as T
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
}
class Test {
var num: Int by LazyVar { 5 }
}
val a: Int = Test().num
Note, that this code is not thread-safe. Also with this code sample you can't set null value for you field (so no way back to default value).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.