2
votes

When using reflection to investigate collection classes, mutable and immutable classes for the same type are referentially equal.

Why is this the case?

    @Test
    fun demonstrate_mutableAndImmutableClassesAreTheSame() {
        println("(MutableIterable::class === Iterable::class) = ${(MutableIterable::class === Iterable::class)}")
        println("(MutableCollection::class === Collection::class) = ${(MutableCollection::class === Collection::class)}")
        println("(MutableList::class === List::class) = ${(MutableList::class === List::class)}")
        println("(MutableSet::class === Set::class) = ${(MutableSet::class === Set::class)}")
        println("(MutableMap::class === Map::class) = ${(MutableMap::class === Map::class)}")
        println("(MutableMap.MutableEntry::class === Map.Entry::class) = ${(MutableMap.MutableEntry::class === Map.Entry::class)}")
    }

prints

(Iterable::class === MutableIterable::class) = true
(Collection::class === MutableCollection::class) = true
(List::class === MutableList::class) = true
(Set::class === MutableSet::class) = true

1
In the platform (JVM) both are the same. You cannot make overload of those types because they are the same at runtime as well see this. The docs mention this as well hereAnimesh Sahu
Might be worth noting that this is only true when kotlin-reflect is included as a dependency (otherwise all results are false.) This also does not apply to Kotlin/JS (and presumably also native, but I haven't tested that.)Salem

1 Answers

1
votes

Collection and MutableCollection are mapped to the same java.util.Collection class (mapped-types), so from POV of JVM (after compilation at runtime) that they are the same.

If you decompile the code you've written, you'll get this (I've decompiled it using Kotlin Bytecode generated by Intellij):

Kotlin:

fun demonstrate_mutableAndImmutableClassesAreTheSame() {
    println("(MutableCollection::class === Collection::class) = ${(MutableCollection::class === Collection::class)}")
}

Java:

import kotlin.jvm.internal.Reflection;

// class declaration
public static final void demonstrate_mutableAndImmutableClassesAreTheSame() {
    String var0 = "(MutableCollection::class === Collection::class) = " + (Reflection.getOrCreateKotlinClass(Collection.class) == Reflection.getOrCreateKotlinClass(Collection.class));
    boolean var1 = false;
    System.out.println(var0);
}

References: