Search code examples
kotlinhashmapnullable

Kotlin non nullable map allows remove null


Why this code can be compiled and executed without erros?

val map = HashMap<Int, Long>()
val key :Int? = null
map.remove(key)

In MutableMap remove declared as accepting only non nullable key, so it shouldn't even compile. Is it a Kotlin type inference bug or am I missing something?

public fun remove(key: K): V?

Solution

  • In this case, map.remove(key) doesn't not calls

    public fun remove(key: K): V?
    

    It calls an extension remove function:

    public inline fun <@OnlyInputTypes K, V> MutableMap<out K, V>.remove(key: K): V? =
        @Suppress("UNCHECKED_CAST") (this as MutableMap<K, V>).remove(key)
    

    This function documentation says that it allows to overcome type-safety restriction of remove that requires to pass a key of type K.


    It allows overcoming type-safety restriction because the key of the entry you are removing does not have to be the same type as the object that you pass into remove(key); the specification of the method only requires that they be equal. This follows from how the equals() method takes in an Any as a parameter, not just the same type as the object.

    Although it may be commonly true that many classes have equals() defined so that its objects can only be equal to objects of its own class, there are many places where this is not the case. For example, the specification for List.equals() says that two List objects are equal if they are both Lists and have the same contents, even if they are different implementations of List. So, for example, according to the specification of the method, it is possible to have a MutableMap<ArrayList<Something>, Something> and call remove(key) with a LinkedList as an argument, and it should retrieve the key which is a list with the same contents. This would not be possible if this extension remove(key) didn't exist.[1]