Collection<T>.toArray() extension function


I'm studying this extension method in JavaUtil.kt


inline fun <T> java.util.Collection<T>.toArray() : Array<T> {
  val answer = Array<T>(this.size)
  var idx = 0
  for (elem in this)
  answer[idx++] = elem
  return answer as Array<T>

because I am finding that these two ArrayList<String> are not equal:


val a = arrayList(“a”, “b”, “aa”)
val b = arrayList(a.toArray())

In the IDE, the “as” in the extension function return statement is browned-out, with a tooltip that says “This cast can never succeed”.  I don’t understand why the “as Array<T>” is needed at all.  When I remove it, the “answer” in “return answer” goes red, with a error that says “inferred type was Array<T?> but expected Array<T>”.

Why is the “as Array<T>” needed, and why is the inferred type Array<T?> if I remove it?


There are two issues. One is real, and one is not :)

The real issue is that you can’t create an array of T without initializing it. In Java we are used to doing this, but there arrays are initializaed with nulls, thus in Kotlin it should be Array<T?>.

The other issue is when we included this function into the Kotlin standard library:

fun Array<T>(val size : Int) : Array<T?> // the implementation initializer the array with nulls

So the call to Array<T>(this.size) up there is not an Array constructor, but a call to this function. This is an unfortunate design decision and we are going to remove it.