I am new to Kotlin and came across many instances in documentation where the common
, js
, native
and jvm
tags list different return values or class types. Could anyone please explain what exactly does that mean?
Here is an example:
My two question here are:
- How are
class
,typealias
andopen class
different? - Why do they seem to return different values for creating the same thing?
CodePudding user response:
The documentation is telling you what you can expect the declaration of LinkedHashMap
to look like, when writing code on different platforms - Kotlin/JS, Kotlin/JVM, Kotlin/Native. The "common" declaration is sort of the "intersection" of the other three - the "common" things among the three, which is useful if you are writing cross-platform code.
To explain each in detail (notice all 3 platforms is a "superset" of common):
Common:
class LinkedHashMap<K, V> : MutableMap<K, V>
LinkedHashMap
is a class that has two generic parameters K
and V
, and it implements MutableMap<K, V>
.
JVM:
typealias LinkedHashMap<K, V> = LinkedHashMap<K, V>
LinkedHashMap<K, V>
is a typealias (i.e. another name) for Java's java.util.LinkedHashMap<K, V>
class. The package name java.util
is not shown in the documentation itself, which might be confusing, but you can click on the link to find out :)
Notice that java.util.LinkedHashMap<K, V>
implements java.util.Map<K, V>
, which when ported to Kotlin, means that it implements MutableMap<K, V>
. (I say this because this is one of the things in the common declaration)
JS:
open class LinkedHashMap<K, V> :
HashMap<K, V>,
MutableMap<K, V>
LinkedHashMap
is a class that has two generic parameters K
and V
, and it implements MutableMap<K, V>
. It also inherits from HashMap<K, V>
, and it is open
, which means that you can inherit from it.
Native:
typealias LinkedHashMap<K, V> = HashMap<K, V>
LinkedHashMap<K, V>
is just another name for HashMap<K, V>
(this time it's Kotlin's kotlin.collections.HashMap
, not Java's. Click the link to find out.) Also note that HashMap<K, V>
implements MutableMap<K, V>
too.
Why do they seem to return different values for creating the same thing?
These are not functions, and they don't return anything. These are declarations for the class LinkedHashMap
, and some platforms may declare them differently, because they're different platforms! For example, why would Kotlin/JVM make an entirely new LinkedHashMap
, when there is already one in the JDK? So they just say that kotlin.collections.LinkedHashMap
is just another name for java.util.HashMap
. Another example is Kotlin/Native: it appears that the HashMap
that they implemented is already linked, so again, we don't need a totally new class.
As long as what they implement on these different platforms satisfy the requirements of the "common" declaration (namely two generic type parameters K
and V
, and implements MutableMap<K, V>
), they're fine.
CodePudding user response:
First and foremost, most of the information in the docs is not relevant, when on the JVM. If you type LinkedHashMap<String, String>()
, you actually (because of the JVM only type alias) create a java.util.LinkedHashMap, thus the way the LinkedHashMap of kotlin is “implemented” on the JVM is using the java built-in. If you call linkedMapOf, however, you get back an instance of the kotlin.collections.LinkedHashMap<K, V> class, but if you look at the reflected type (::class) it is actually still a java.util.LinkedHashMap! So, we can conclude the following out of this:
- On the JVM, collection types of the java stdlib are used (because the compiler changes constructor invocations to kotlin collections, to invocations of java ones)
- There is a common class or interface that exists so you don’t have to write different code on different platforms, a different type may be used on runtime, however.
- When using JS, LinkedHashMap can be overridden (because it is
open
), and it is the “implementer” of the expected LinkedHashMap type. - When using native targets, because the order is preserved when using a normal HashMap, LinkedHashMap points to there because there is no reason for using a linked hashmap instead of a normal one
Edit: just realized I didn’t really answer your question:
- a class is just your regular oop class, but it can’t be overridden because it is open, typealias means that when you reference a certain type it actually “points” to a different type (you can see it as a type rename, or reexport), and an open class is a class that can be extended/overridden
- Because of platform-specific implementations. This structure or expect actual allows you to write common code for all platforms without having to worry about an individual platform.
I hope this answers your questions, let me know if you have any more.