But my main question concerns this piece of code:
var mapCustomers: IMap<Int, String>? = instance?.getMap("customers"); mapCustomers = null; val myMap = mapCustomers as java.util.Map<Int, String>
The code above compiles and runs and of course creates a kotlin.TypeCastException in the 3rd line. My question is whether the compiler shouldn't have complained that it must be
?
instead of
mapCustomers as java.util.Map<Int, String> // no question mark
because it knows that mapCustomers in the 1st line was declared with an ?
I guess, that's exactly like in Java: Any cast is legal as long as the compiler can't proof that it must always fail. In this case it may succeed. It could fail for two reasons:
- mapCustomers being an incompatible instance
- mapCustomers being null
- Given the statement
mapCustomers = null;
Kotlin could prove that the cast must fail. It does similar things in if-blocks
- Unfortunately, casting allows changing multiple things at once: the exact type, nullability, generics(?), whatever. This may lead to casting more than expected (as you did). There’s already a specialized “null cast”, namely the !! operator. Maybe there could be a cast allowing nothing but changing the erased type itself. I mean something like
var mapCustomers: IMap<Int, String>? = instance?.getMap(“customers”);
val myMap = mapCustomers restricted_as java.util.Map<…>?
You wouldn’t have to repeat all the generics and you couldn’t cast away nullability by mistake.