Unexpected behaviour found in K/N: ``` val r = At...
# kotlin-native
a
Unexpected behaviour found in K/N:
Copy code
val 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.
d
It's boxed again, so object is different.
And seeing the size of that number, the object won't be recycled.
a
Yep and this is unexpected
Since same code works fine on JVM
The actual type of the variable
v
is
Long
in JVM
For me it looks like a bug in compiler, there is no reason to unbox the value.
o
There’s no such code in JVM, K/N atomics are different. Code above makes not much sense in Kotlin, as primitive types got no identity and CAS relies on identity.
s
The actual type of the variable
v
is
Long
in JVM
No, it is
Long!
, which is still boxed.
Since same code works fine on JVM
Try this:
Copy code
val r = AtomicReference(1000L)
val v = r.get()!!
println(r.compareAndSet(v, 2000L))
Or this:
Copy code
val r = AtomicReference(1000L)
val v: Long = r.get()
println(r.compareAndSet(v, 2000L))
a
This is exactly what I'm talking about. And the type is
Long!
because AtomicReference is the Java class not Kotlin. The following code prints
false
in all platforms:
Copy code
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
.
s
You can use
Long?
in Kotlin. Generally Kotlin doesn’t guarantee anything about identity of primitive types.