如何解决Kotlin 地图/列表可空类型安全
我是 kotlin 的新手,所以我的问题需要一些关键字。
这是我的 kotlin 代码:
fun foo(map: Map<String,Int>) {
map.forEach {
println(it.value.toString())
}
}
当如下调用时,此代码段可能导致 NPE:
fun main() {
val map = mapOf("bar" to null) as Map<String,Int>
foo(map)
}
- 我不知道为什么这个转换
mapOf("bar" to null) as Map<String,Int>
可以在没有编译错误的情况下工作。 - 不知道为什么函数
foo
会导致 NPE 而它没有编译错误或警告或!!
我确定有类似的问题,但我找不到问题或任何关键词。
实际上我使用这张地图:
val objectMapper = jacksonObjectMapper()
val string = """
{ "value": null }
""".trimIndent()
// this is an example,origin string comes from RESTAPI input.
val convertedMap: Map<String,String> = objectMapper.readValue(string)
并且它没有发出任何警告,并且导致了 NPE。 我需要一些使用 kotlin Map/List 的技巧,以免出现意外错误。
解决方法
铸造本质上是不安全的。你告诉编译器你比编译器更了解你正在转换的对象。在某些情况下,编译器会在转换时给您一个错误,当它可以告诉您正在转换的内容不可能与其他类型匹配时。
当您转换为没有泛型的类时,您通常不会收到任何警告。假设与 !!
一样,如果您正在投射,您就知道自己在做什么。您已经检查了可能的逻辑并且可以绝对确认强制转换是安全的,即使编译器无法判断。
当您转换为具有泛型的类时,编译器至少会给您一个警告。这是因为如果泛型类型错误,则转换不会失败。它会因为类型擦除而成功,然后当您开始与对象交互时,您将在代码中的其他地方收到错误。所以出现警告是因为它比 ClassCastException 更糟糕,因为由此产生的错误发生在代码中的其他地方,而不是执行强制转换的行,这使得调试变得更加困难。
抑制警告只会使警告消失。它根本不会改变行为。仅当您检查了警告可能导致的故障并确定您正在执行的操作是安全的时,才禁止显示警告。
就您的 Map 而言,尽管它包含空值,但将其转换为不可为空的值会在运行时成功,但稍后在检索值时会失败。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。