Can no longer iterate over a java.util.Collection, java.util.Iterator or Object[] which comes from a Java API


#1

Lots of kotlin code just stopped compiling for me of the form:

for (e in javaObject.getCollection()) {   ... }

for example iterating over java.util.ServiceLoader which has an iterator() method no longer compiles. (Confusingly the compiler error message is that the type has no iterator() method - when it clearly does). I've lots of other cases where a Java class returns a (not null) collection which I can now no longer just iterate over.

Having Java APIs which have methods which return a Java collection are very common. However you can no longer do the above since the iterator() methods return a possibly null iterator. You now have to replace this code with…

for (e in javaObject.iterator()!!) {   ... }

or

``

for (e in javaObject.getCollection().iterator()!!) {
  …
}

While technically there’s a possibility that a collection/iterator may be null so the compiler may be being more correct, I’d argue this is leading to unnecessarily verbose ugly code. If someone really really wanted to throw an NPE for a not-really-ever-going-to-happen possible null being in there, they could still use the explicit verbose alternative.

I guess one day someone will have spent the time to go through every Java API on the internet and add the correct not null type signatures to every method on every class for kotlin; until then the for expression is going to be pretty ugly in kotlin when using Java APIs


#2

You can use external annotations to tell the compiler that the things you are iterating over are not null.


#3

Unfortunatley I don't yet have time to annotate all the Java code on the internet. Have we got any volunteers?


#4

:)

I volunteer to annotate all the code I happen to use. Do you think this model works?