I noticed that when I have a var
property with a custom get
, that does not use the field
identifier, a backing field is generated anyway. I checked the bytecode, and the documentation says so as well:
A backing field will be generated for a property if it uses the default implementation of at least one of the accessors, or if a custom accessor references it through the field identifier.
(emphasis is mine)
Consider a class like this. Since it's a var
property, a default set
(and therefore a backing field) will be generated:
class Banana {
var ripeness = 1
var color: String = "green"
get() = when {
ripeness > 80 -> "brown"
ripeness > 50 -> "yellow"
else -> "green"
}
}
val b = Banana()
b.color = "blue"
println(b.color)
However, the println
will always print "green", no matter what I set color
to. The backing field will be set to "blue" anyway.
Since there is no way to access it outside the accessor methods (or via reflection) I really can't think of a reason for this.
Am I missing something here? Maybe a usecase or another way of accessing the backing field? Or is it just a bug (or a missing warning in IntelliJ)?
Beware of val ... get(), the behavior migth be very surprising:
class Val {
val millis: Long = System.currentTimeMillis()
}
class ValGet {
val millis: Long
get() = System.currentTimeMillis()
}
val v = Val()
val g = ValGet()
for(i in 0..4) {
println("val:" + v.millis + " valget:"+g.millis)
Thread.sleep(7)
}
What's the use of val
if a val x: Int
cannot be relied upon to be the same when referenced twice? Apparently it even works for overrides if the parent is sufficiently open, an abstract val looksQuiteLikeImmutable : Int
can be very misleading. Feels like groovy all over again... (At least this is what I observe in 1.4.21)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With