I understand that a Map<String,Boolean> isn’t strictly the same thing as a Map<String?,Boolean> – so what’s the simplest way to convert the map so that I can pass it in? I feel like there ought to be a simple way to do this, but I haven’t figured out what the simple way is.
You have to either specify the type of mapping variable or call mapOf with explicit type parameters.
Yeah, sorry, the example is a simplification of reality. I have a Map<String,morestuffhere> that I get from somewhere else, I know how to make my own Map<String?,morestuffhere>, I’m just wondering what the cleanest way of converting the map I already have to the nullable-key version is.
Note that such a cast is unsafe. The implementation of doSomething() could call get(null) on the map (which would be perfectly legal, as its parameter explicitly allows a null key). The cast could then cause a null-pointer exception.
The cast could then cause a null-pointer exception.
Sorry, where’s the potential NPE? The biggest potential problem to me is that doSomething() could insert a null into the map which the caller could then access, not expecting a potential null, but that’s always a bit of a risk with generics given type erasure.
>>> fun doSomething( mapping: Map<String?,Boolean> ) {
... println("mapping[null]: ${mapping[null]}")
... }
>>> doSomething(mapOf(null to false))
mapping[null]: false
>>> doSomething(mapOf("A" to true) as Map<String?,Boolean>)
mapping[null]: null
The problem could be if the map is not backed by a java map but by a custom implementation in kotlin. In that case mapping[null] will fail with a NPE.
class MyMap<K: Any, V: Any>(val m: Map<K, V>): Map<K, V> by m {
override operator fun get(key: K): V? = m[key] // kotlin will generate a null check for key, which would lead your code to fail
}
That said, as long as you are sure that you are only dealing with java standard library maps you should be fine.
In this case it’s definitely being created by mapOf(), which in its current implementation seems to be a LinkedHashMap, although there’s no guarantee that can’t change in the future, so there’s still some risk there in theory.