Arkadii Ivanov
06/30/2019, 7:43 PMval r = AtomicReference(1000L)
val v = r.value
println(r.compareAndSet(v, 2000L))
The code above prints false
. Line val v = r.value
unboxes the value so compareAndSet
is called with new instance of Long
and fails. I am aware of AtomicLong
, I'm trying to write some inline extensions for AtomicReference
and they fail if type T
is primitive.Dominaezzz
06/30/2019, 8:45 PMDominaezzz
06/30/2019, 8:45 PMArkadii Ivanov
06/30/2019, 8:46 PMArkadii Ivanov
06/30/2019, 8:46 PMArkadii Ivanov
06/30/2019, 8:46 PMv
is Long
in JVMArkadii Ivanov
06/30/2019, 8:47 PMolonho
07/01/2019, 6:14 AMsvyatoslav.scherbina
07/01/2019, 9:02 AMThe actual type of the variableNo, it isisv
in JVMLong
Long!
, which is still boxed.
Since same code works fine on JVMTry this:
val r = AtomicReference(1000L)
val v = r.get()!!
println(r.compareAndSet(v, 2000L))
svyatoslav.scherbina
07/01/2019, 9:02 AMval r = AtomicReference(1000L)
val v: Long = r.get()
println(r.compareAndSet(v, 2000L))
Arkadii Ivanov
07/01/2019, 9:09 AMLong!
because AtomicReference is the Java class not Kotlin. The following code prints false
in all platforms:
fun bar() {
val pair = 1000L to "abc"
val value = pair.first
foo(pair.first, value)
}
fun foo(a: Any, b: Any) {
println(a === b)
}
The question now is why compiler unboxes the value and how we can prevent it? In Java there are different types, in Kotlin it's just Long
.svyatoslav.scherbina
07/01/2019, 9:22 AMLong?
in Kotlin.
Generally Kotlin doesn’t guarantee anything about identity of primitive types.