简体   繁体   中英

In Kotlin, why does mutableListOf return an instance of java.util.ArrayList, while listOf returns an instance of java.util.Arrays$ArrayList?

In Kotlin, the mutableListOf method returns an instance of java.util.ArrayList that implements Kotlin's MutableList interface.

Now, the listOf method returns an instance of java.util.Arrays$ArrayList that implements Kotlin's List interface.

From what I understand, List and MutableList are just meant to be two different "views" of ArrayList, immutable and mutable. Why do they map to seemingly different ArrayList classes when they are, as juxtaposing interfaces, what defines the behavior and use of an ArrayList in Kotlin?

What is the difference between java.util.ArrayList and java.util.Arrays$ArrayList? I couldn't find anything about the latter in the java docs. This question stems from what this code outputs in the console:

val list = listOf(1, 2, 3)
val mutableList = mutableListOf(1, 2, 3)

println( list.javaClass )           // class java.util.Arrays$ArrayList 
println( mutableList.javaClass )    // class java.util.ArrayList 

Why do they map to seemingly different ArrayList classes when they are, as juxtaposing interfaces?

Interfaces don't "map to" classes. Interfaces specifies a set of requirements. If a class implements an interface, it means that it meets all the requirements specified in that interface .

listOf returns an object that is capable of doing all the things listed in the List interface. That's what it means for a function to be declared to "return a List " Similarly, mutableListOf returns an object that is capable of doing all the things listed in the MutableList interface.

It does not matter which specific type of object that the methods return, as long as they are capable of doing the things specified in the interface. Which specific kind they return, ie listOf(...)::class and mutableListOf()::class are implementation details . Because they are implementation detail, you should not take it as "absolute truth" and say things like " listOf returns an java.util.Arrays$ArrayList ". In fact, it doesn't. At the time of writing, listOf<Integer>()::class is class kotlin.collections.EmptyList .

Anyway, java.util.Arrays$ArrayList is an immutable list. It's a private inner class in java.util.Arrays . You'd usually see this class in Java when you do Arrays.asList , which serves a similar purpose to listOf , but again, this is an implementation detail. On the other hand, java.util.ArrayList is mutable.

Though listOf could have been designed to return an ArrayList (this is totally fine), and its mutable nature could be hidden behind the immutable List interface (which ArrayList also implements), it could be speculated that returning an Arrays$ArrayList is preferable because 1) it does not create a copy of the array you passed to listOf . 2) It does implement List .

Well, java.util.Arrays$ArrayList is a nested class inside Arrays class. The main difference between java.util.Arrays$ArrayList and java.util.ArrayList is that the first has fixed length while the latter's length can grow. Both lists are backed by arrays.

java.util.Arrays$ArrayList will also be return type of Arrays.asList which used to create immutable list from an array.

That is the reason, why MutableList inherits from java.util.ArrayList and List on the other hand inherits from java.util.Arrays$ArrayList since it is immutable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM