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?
CodePudding user response:
I just realized the answer, if you are using Map like Map<String, String>
in Kotlin there is a mutable and immutable version of it. In the question above all you need to do is to convert it to immutable Map using toMap()
.
val msgData = parser.fromJsonString<CommonNotification>(
JSONObject(remoteMessage.data.toMap()).toString(),
CommonNotification::class.java
) ?: return
CodePudding user response:
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