Contravariance in Kotlin

Viewed 690

I never truly understood generics in Java, so it seems to be the case with Kotlin. Consider the following code snippet (it's a contrived example):

class AnyComparator: Comparator<Any> {
    override fun compare(o1: Any, o2: Any): Int {
        TODO("not implemented")
    }
}


fun <T> test() {
    val x: Comparator<in Double> = AnyComparator() // OK!
    val y: Comparator<in T> = AnyComparator() // Compilation error
}

The second assignment fails with the error

Type mismatch. 
Required: kotlin.Comparator<in T>
Found: AnyComparator

Now, if I understand correctly the in modifier indicates the T is only consumed by the generic type Comparator (it makes contravariant), so I should be able to assign any Comparator with type argument E which is the base class of T. Based on this, I should be able to assign AnyComparator to both variables x and y, since the type Any is the base class of every class in Kotlin. It turns out I can't, and I don't understand why.

2 Answers

Just to add to the Fabio answer, Any? is not a superclass of all the classes in kotlin but Any is a subtype of Any? to be technically correct. For Example:

    val string1: String = "Sarabjit"

// val newString2 : String = null [this does not work as we cannot assign null to a String which cannot hold a null value

    var checkString: String? = newString1

checkString = null //This works like a charm.
Related