Hi All. I'm in the process of migrating a service,...
# announcements
t
Hi All. I'm in the process of migrating a service, written in a combination of Java 8 and Kotlin, to Java 16. I am seeing some bizarre behaviour that I can't find an explanation for. The code below ends up with notTheSame set to true, when someField has the value of 2, which is the same as the value of the constant it is being compared with. (someField is read from a database). The (obviously modified) code shows the comparison:
Copy code
fun isXXX(current: Foo, previous: Foo?): Boolean {
	val notTheSame = previous?.someField != someConstant
	if (notTheSame) {
		println("${previous?.someField} != $someConstant")
	}
	...
}
The data class:
Copy code
data class Foo(
    ...
    var someField: Short = initial,
	...
)
The constants:
Copy code
const val initial: Short = -1
const val someConstant: Short = 2
Could someone please help me understand the cause, or point me to where I should look? Code hasn't been touched for over a year, and I'm updating every single JAR used at the same time. Thanks.
s
can you try logging
current
and
previous
? Also, its best to use a debugger to find issues in such buggy code. We dont have a full picture, and it will take more time to explain for you to than just debug/log it.
t
Thanks. I'm already logging current and previous and also debugging. Logging shows 2 != 2. And debugger shows both the constant and the value being compared is 2.
My problem is best illustrated by this debugger screenshot. The expression assigned to a val has a different value than the exact same expression evaluated in the debugger. (There is only a single thread accessing the data).
image.png
Turns out the issue is because the compiler is generating code to convert the constant to an Integer. And then calling Intrinsics.areEqual, which ends up in Short.equals(). The comparison fails because a Short is never equal to an Integer. Workaround is to stop using Short!