Playing with null-safety: Is this an error?

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 declaration, none of the cases is sure. This brings me to two things:
  1. Given the statement

mapCustomers = null;

Kotlin could prove that the cast must fail. It does similar things in if-blocks

  1. 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.