Platform types and immutable collections

Kotlin features like null safety are enforced during compile time and Kotlin tries to have (great) interoperability with Java. When Java code calls your Kotlin code it is already compiled and the Kotlin compiler cannot enforce its null checks. This is the reason why the Kotlin development team introduced a concept of a Platform Type. Simply put, a Platform Type is a type defined in Java (or any other JVM language).

In the case of nullability, Kotlin code can handle them as either nullable or non-nullable. If during runtime a null value is passed to a non-nullable variable, the Kotlin runtime will throw a null pointer exception.

Immutable Kotlin Collection types are treated similarly. Remember, Kotlin doesn’t define its own Collection type, instead it uses the ones from Java. Since Java doesn’t have the same concept of mutable and immutable collections (Java has immutable collections with specific types, such as the UnmodifiableList) it is up to the Kotlin code to treat them as mutable or immutable. This is not something you usually need to worry about. 

But if you are communicating in the other direction, i.e. calling Java from Kotlin, then you have to be a bit more careful. Take a look at the following Java function: 

public void checkStrings(List<String> strings) {
for (String s : strings) {
// do something
}
strings.add("Item added in Java");
}

We can imagine it does some string processing or validation and then it appends an item to the list. And we can pass an immutable list from Kotlin to it, as follows:

val strings = listOf("Item added in Kotlin", "Another item added in Kotlin")
// UnsupportedOperationException thrown here
java.checkStrings(strings)

But calling this Java function will throw an UnsupportedOperationException during runtime. The reason is that the listOf function creates a specific implementation of the List interface, one that extends the AbstractList class and doesn’t override the add method from it. The base implementation of the AbstractList add method just throws the UnsupportedOperationException. In cases like this, where you know that Java code is mutating a collection, always pass some version of a mutable version from Kotlin.

Now that you know how Kotlin Collection types use the corresponding Java types, and how Kotlin enforces collections immutability during compile time, it is easy to trick the compiler and modify the immutable collection with a simple cast. Consider this example where we declare an immutable list variable, assign to it an instance of the ArrayList class and then with a simple cast we are able to add more items to it:

val list: List<String> = ArrayList()
val mutableList = (list as ArrayList).add("string")

Finally, in the same way as with mutable and immutable properties, you should favor immutable collections. This can make your code have clearer intentions. For example, if you accept an immutable list as your parameter, then a user of your API knows that you are not modifying the collection with your code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.82.82