How to create an immutable list in Kotlin, which is also an immutable list in Java?

I have a Java / Kotlin interaction problem. Kotlin's immutable list is compiled into regular java.util.ArrayList, which is changed!

Kotlin (library):

class A { val items: List<Item> = ArrayList() } 

Java (consumer):

 A a = new A(); a.getItems().add(new Item()); // Compiles and runs but I wish to fail or throw 

How to make my Kotlin class completely immutable from a Java perspective?

+6
source share
1 answer

All non- Mutable____ collections in Kotlin are, by default, compiled read-only , but not immutable . See the following code snippet:

 fun main(args: Array<String>) { // Explanation for ArrayList(listOf()) later down the post val list: List<Int> = ArrayList(listOf(1, 2, 3)) println(list) // [1, 2, 3] // Fails at compile time // list.add(4) // Uh oh! This works at runtime! (list as MutableList<Int>).add(4) println(list) // [1, 2, 3, 4] } 

To really have an immutable list, consider the Guava Immutable____ collections:

 import com.google.common.collect.ImmutableList fun main(args: Array<String>) { val list: List<Int> = ImmutableList.of(1, 2, 3) println(list) // [1, 2, 3] // Fails at compile time // list.add(4) // Fails at runtime, as expected (list as MutableList<Int>).add(4) println(list) // [1, 2, 3, 4] } 

Keep in mind that some of the standard Kotlin runtime functions can return collections that cannot be resized, are not resized, etc., so all bids are disabled when you directly pass a read-only collection to mutable.

For example, listOf() is currently (this may change in the future!) Returns java.util.Arrays.ArrayList around an array of vararg parameters via Arrays.asList(T...) . This "list" can be changed, but items can never be added or removed, since you cannot resize the array. See Arrays.asList(T...) javadoc for more details.

If you really need a mutable collection from any collection, try making a copy using .toMutableList() . This will work in any collection:

 import com.google.common.collect.ImmutableList fun main(args: Array<String>) { val list: List<Int> = ImmutableList.of(1, 2, 3) val copy = list.toMutableList() copy.add(4) println(copy) // [1, 2, 3, 4] println(list) // [1, 2, 3] } 
+10
source

Source: https://habr.com/ru/post/1012262/


All Articles