I've noticed this peculiarity: ```val a: Int = foo...
# getting-started
k
I've noticed this peculiarity:
Copy code
val a: Int = foo()
val b: Int? = bar()
if (a < b!!) {...}
else if (a == b) {...} 
else if (a == b + 1) {...}
In the case of
a == b
it calls
Int.equals(Any?)
so it boxes
a
and then compares it to the boxed
b
. But for
a == b + 1
it smart-casts
b
as
Int
. Why doesn't it smart-cast
b
in the first case?
g
Compiler assumes that if unsafe cast
b!!
did not throw any exception then
b
is
Int
. Thus, it smarcasts
b
in
a == b + 1
in
Copy code
if (a < b!!) {} else if (a == b + 1) {}
in the same way as it smartcasts
b
in
a < b
in
Copy code
if (a == b!! + 1) else if (a < b) {}
k
Yes, but in that case it has to smart cast
b
because you can can't do the
+
and
<
operations on
Int?
but they can be done on
Int
and so the smart cast is necessary. But my question is why does it not smart cast
b
in the expression
a == b
? It can but chooses not to, and prefers to box
a
instead of comparing primitives.
g
@Klitos Kyriacou maybe because RHS operand of
+
in (
b + 1
) is an int, the compiler converts
b
to int. So the resulting value has the type int. So now you have
a == <some int>
, so the compiler converts
a
to int
k
No,
a
is already an Int.
g
@Klitos Kyriacou what is the type of
b + 1
?
k
b + 1
is an Int.
Actually, looking at the generated bytecode, I think I was mistaken about what the expression
a == b
does. It's just IntelliJ IDEA says
b
is not smart-cast, but it seems the compiler does indeed smart-cast it.