Рассмотрим следующий код:
val myarray = arrayListOf("hello", "world")
println(myarray)
println(myarray::class.java.name)
val arrayString = mapper.writeValueAsString(myarray)
println(arrayString)
println(arrayString::class.java.name)
val myMap = HashMap<String, String?>()
myMap["key"] = JsonPath.read<String>(arrayString, "$")
println(myMap["key"])
println(myMap["key"]!!::class.java.name)
Этот код создает ArrayList, содержащий значения «hello» и «world», преобразует список в строку json, считывает корневой элемент json (который является универсальной функцией, для которой требуется вернуть строку) и сохраняет его в HashMap
Этот код компилируется и выполняется без ошибок и выдает следующий вывод:
[hello, world]
java.util.ArrayList
["hello", "world"]
java.lang.String
["hello","world"]
net.minidev.json.JSONArray
Как myMap["key"]
возвращает JSONArray
? (напомним, что myMap был объявлен как <String, String?>
)
Kotlin проверяет его тип во время компиляции, но поскольку универсальная функция JsonPath.read
сообщает, что она возвращает String
, компиляция происходит нормально.
Тогда, похоже, JsonPath.read
нарушает свой контракт и возвращает JSONArray
вместо String
. Kotlin, похоже, не проверяет тип и позволяет хранить JSONArray
в пределах Map<String, String?>
.
Нет ошибок, если я не попытаюсь использовать myMap["key"]
как String
Примечание
Эту проблему можно решить, изменив строку, которая читает json:
myMap["key"] = ObjectMapper().writeValueAsString(JsonPath.read<String>(arrayString, "$"))
EDIT
Пример кода без использования JSON Madness:
fun <T> myFun(): T {
return 7 as T
}
fun test() {
val map = HashMap<String, String?>()
map["key"] = myFun<String>()
println(map["key"])
println(map["key"]!!::class.java.name)
}
returns:
7
java.lang.Integer