ArrayList is not compatible with List

Hi,

I wonder why this example doesn’t work in Kotlin:

data class Example(val l: java.util.List<String>)

fun main(args: Array<String>) {
    Example(java.util.ArrayList<String>())
}

The error message is:

Type mismatch: inferred type is java.util.ArrayList<kotlin.String> but java.util.List<kotlin.String> was expected

But why is it not possible to pass a java.util.ArrayList where a java.util.List is expected?

The same works fine in Scala:

scala> case class Example(l: java.util.List[String])
defined class Example

scala> Example(new java.util.ArrayList[String])
res1: Example = Example([])

How can I achieve the same in Kotlin?

You aren’t supposed to use the qualified java.util.List names in Kotlin - why are you writing it like that?

If you tak out the “java.util.” does it work for you?

If I don’t qualify the name, a Kotlin List gets used, but I want a java.util.List, because I’m using it with Hibernate.

I still don’t understand, why a java.util.ArrayList is not compatible with a java.util.List in Kotlin. This violates the Liskov subsitution principle.

If I don’t qualify the name, a Kotlin List gets used, but I want a java.util.List, because I’m using it with Hibernate.

kotlin.List is effectively an alias for java.util.List: when you use it in the code, java.util.List appears in the byte code. So, all you need is use it and not worry :slight_smile:

I still don’t understand, why a java.util.ArrayList is not compatible with a java.util.List in Kotlin. This violates the Liskov subsitution principle.

As mentioned above, Kotlin has variant collection interfaces that are desugared into plain Java collections in the byte code. Because of this, Kotlin sees ArrayList as a subtype of kotlin.List and not java.util.List. As a result, we can use collections in a new, safer way and have no issues with Java interop, because Java still sees the collection as normal java.util.* ones.

Thank you, for the explanation! Maybe I’m a bit to careful here after bad experiences with Scala and Hibernate … Now I stop worrying and start using kotlin.List :wink:

1 Like