Type mismatch: inferred type is java.util.ArrayList<org.example.domain.OrderDetail> but java.util.List<org.example.domain.OrderDetail> was expected


#1

Hi,

I have a class with:

  public var details: List<OrderDetail> = ArrayList<OrderDetail>();

… and I get a compile error saying:

Error:(234, 21) Kotlin: Type mismatch: inferred type is java.util.ArrayList<org.example.domain.OrderDetail> but java.util.List<org.example.domain.OrderDetail> was expected

I’m trying to figure out why this is?  

Thanks, Rob.


#2

Hi Rob,

what happens if you try this:

val list: kotlin.MutableList<Foo> = ArrayList()

or this:

val list: kotlin.List<Foo> = ArrayList()

This gives the same compiler error as you reported in your case:

val list: java.util.List<Foo> = ArrayList()

I had recently the same problem, but with Maps, see http://devnet.jetbrains.com/thread/457372?tstart=0 Note, that you don't need to repeat the type parameter. Just ArrayList() will do.


#3

Great thanks - yes that works.

For me I’ve ended up as:

  public var details: MutableList<OrderDetail> = ArrayList();


#4

I think the purpose is to make developers make up their minds whether to go with a MutableList or ImmutableList. Seems like a good idea to me, because immutability really helps in reducing bugs. However, everybody knows that java.util.ArrayList implements java.util.List. So when something like "val list: java.util.List<Foo> = ArrayList()" does not compile people are really wondering what's happening. By the way you can omit the trailing ";". In Kotlin they are optional as in Groovy.

Regards, Oliver


#5

There are no docs on mutable vs immutable collections, as far as I can tell. That's not great. The only explanation of this is the blog post announcing M3.

There should be a section on the website explaining how this feature works.


#6

Maybe the compiler error or error in the IDE could be a bit more descriptive. That would also help. Besides that the issue is a bit strange. If java.util.ArrayList implements java.util.List then  "val list: java.util.List<String> = java.util.ArrayList()" should compile as "val list: java.util.List[String] = new util.ArrayList()" does in Scala.


#7

Yes better docs and a better compiler error would be good.

The big positive for me is in regards to Oliver’s comment about mutable and immutable … and starting the path to ‘thinking in Kotlin’ as opposed to ‘thinking in Java’. An ImmutableList would not allow add()/remove() etc and provide an immutable iterator, immutable subList etc - so in a more ‘Kotlin style’ this is explicit and enforced by the compiler - that is a big positive.

Maybe ‘thinking in Java’ meant I naturally used a java.util.List and actually if I was ‘thinking in Kotlin’ I’d never use java.util.List at all and instead always explcitly use ImmutableList and MutableList and get the compile time safety with that.

Cheers, Rob.