https://kotlinlang.org logo
#getting-started
Title
# getting-started
g

glenkpeterson

01/03/2022, 10:43 PM
Why isn't my JVM Double variable the same as itself in 1.6.10?
Copy code
val dotOne: Double = "0.1".toDouble()
        assertSame(dotOne, dotOne)

expected: java.lang.Double@76774d21<0.1> but was: java.lang.Double@68be905c<0.1>
I understand that
assertSame
uses referential equality (checks that the parameters have the same virtual memory address) and should function like the
===
operator.
0.1 !== 0.1
because they are primitives and could be boxed to different objects before being compared for referential equality. But, when I declare a variable, I would expect it to have the same virtual memory address as itself. Be referentially (and structurally) equivalent to itself. Can I declare my variable somehow to not be compiled away to two different primitives that happen to have different virtual memory addresses?
e

ephemient

01/03/2022, 10:44 PM
no, because the primitive 1.6 does not have a memory address. every time it is boxed, a new object is created.
🙏🏻 1
🙏 2
g

glenkpeterson

01/03/2022, 10:46 PM
So this will be an issue with any boxed primitive type and should work as I expected with any unboxed type?
e

ephemient

01/03/2022, 10:47 PM
the same does not apply to small ints and longs as the JVM keeps a small cache of fixed instances, but it does for large ints and longs, as well as floats and doubles
🙏 1
🙏🏻 1
for further reading: https://medium.com/geekculture/integercache-in-kotlin-java-c2044b12de2c note that while IntegerCache is tunable via
-XX:AutoBoxCacheMax=
as described in the article, LongCache is not tunable, and neither are the
Boolean.TRUE
and
Boolean.FALSE
static instances
🙏🏻 1
g

glenkpeterson

01/03/2022, 10:55 PM
Yay: small cache of fixed instances. But... why is Kotlin boxing and unboxing a variable that's only used when it's boxed? Isn't that wasteful? Also, from your article I learned that I can make it nullable to force a boxed variable, which answers the end of my original question:
Copy code
@Suppress("RedundantNullableReturnType")
val dotOne: Double? = 0.1
assertSame(dotOne, dotOne) // Yup, same!
v

Vampire

01/03/2022, 11:15 PM
I guess a non-nullable "primitive" like
Double
is compiled down to be a real primitve at runtime. And then when you use it as argument to an
Object
method like
assertSame
it gets autoboxed.
2
2 Views