Kotlin: Cannot convert Map to JSON

Bitwise DEVS

How to convert Map to JSONObject? It accepts Map but it seems you need to perform casting. Is there any other way to do this without using library?

enter image description here

Karsten Gabriel

The answer provided by Bitwise DEVS may work, but the explanation is incorrect.

It is not necessary to convert the map into an immutable map - it can even be seen in the screenshot of the question: expected (Mutable)Map means that it can be mutable or immutable.

The real problem here is that the called constructor of JSONObject is defined for Map<Any?, Any?> but the given parameter is of type Map<String!, String!>. We know that String is a subtype of Any?, so why is that a problem?

It is a problem because Map is invariant in the key parameter which means that a Map<A, V> is not subtype of Map<B, V> even if A is subtype of B (and also not if it is the other way around).

The call of toMap does not work because it makes the map immutable, but because it is defined as

fun <K, V> Map<out K, V>.toMap(): Map<K, V>

In the receiver type of toMap the key parameter is annotated with the out modifier, meaning that K is covariant here. This means that a Map<Any, V> in this position can safely be considered as a supertype of Map<String, V>. Additionally, Map is always covariant in its value type, meaning that Map<Any, Any> in this position can safely be considered as a supertype of Map<String, String>.

You could as well just cast remoteMessage.data as Map<Any?, Any?> or use toMutableMap, it would be all the same. It has definitely nothing to do with mutability of the map.

Kotlin documentation on variance: https://kotlinlang.org/docs/generics.html#declaration-site-variance

Kotlin documentation of Map: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/

Definition of toMap: https://github.com/JetBrains/kotlin/blob/ea836fd46a1fef07d77c96f9d7e8d7807f793453/libraries/stdlib/src/kotlin/collections/Maps.kt#L600

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related