This is a question on Type Inference that I posted on StackOverflow. First guess the answer and then look at the SO answer.
I understand that Kotlin is a statically-typed language, and all the types are defined/inferred at the compile time itself.
Here is a
when
expression that returns different types:
Copy code
fun main(){
val x = readLine()?.toInt() ?: 0
val y = when(x){
1 -> 42
2 -> "Hello"
else -> 3.14F
}
println(y::class.java)
}
During runtime (Kotlin 1.3.41 on JVM 1.8) this is the output:
When
to be the upper bound class that cover all the when branches return types.
Or in other words, the super class that is common to all branches result.
Now
KClass<T>.java
is a runtime function call. So it is acting on the actual returned type instance.
👍 2
✔️ 3
a
Animesh Sahu
11/01/2019, 3:39 PM
Using reflection, you get actual class of which instance is of, while in runtime type maybe any supertype, you can declair any integer while storing it as Any type, you cannot do any operation with int since runtime doesn't know about it but if you try using reflection you can actually get the real name of the class of which the instance is of.
✔️ 1
m
Maxim Kizub
11/01/2019, 4:15 PM
Compile-time type of y is Any. But runtime type can be anything that extends Any. You print runtine type, not compile-time type.
✔️ 1
s
Stephan Schroeder
11/01/2019, 4:53 PM
so just to be very explicit:
when
doesn’t return different types, it returns a value of typ
Any
. So you wouldn’t be able to call
y.substring(..)
without casting
y
even if
x=2
.
v
Vishnu Haridas
11/01/2019, 4:59 PM
@Stephan Schroeder AFAIK,
when
returns the nearest supertype of all branches. In this case,
Any
.
If we consider classes
class Foo
,
class Bar: Foo
,
class Baz: Foo
, and a
when
returns
Bar
and
Baz
in different branches, then the inferred type will be
Foo
.
Vishnu Haridas
11/01/2019, 5:01 PM
@Stephan Schroeder Also you are right, we must cast