На самом деле, если вы начинаете с LinkedHashSet
, его объявление выглядит следующим образом:
expect class LinkedHashSet<E> : MutableSet<E> {
expect
однако ожидает фактической реализации, и фактическая реализация этого на JVM равна java.util.LinkedHashSet
, которая затем реализует Serializable
:
@SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>
Относительно Int
все немного сложнее. Там мы не видим никаких expect
. Но мы знаем, что Int
может представлять как примитивный тип Java int
, так и тип Java Integer
. Компилятор фактически использует java.lang.Integer
под капотом, который реализует Serializable
через java.lang.Number
.
Вы можете проверить фактические типы во время выполнения, используя что-то следующее:
val linkedSet = linkedSetOf(linkedSetOf(1, 2, 3), 2)
linkedSet.forEach { content ->
content::class.java.interfaces.joinToString {
it.simpleName
}.also {
println("${content::class.java}: $it")
}
}
Относительно того, как вы можете узнать, реализует ли "стандартный" тип библиотеки Serializable
или нет: помимо обращения к документации, вы можете просто объявить тип явно, если вы хотите обеспечить сериализуемые типы, т.е.
val linkedset : LinkedHashSet<Serializable> = ...
После этого вы получите ошибки времени компиляции, если что-то не будет сериализуемым (за исключением случаев, когда вы выполняете небезопасное приведение, в этом случае вы в основном обманываете компилятор или себя).