繁体   English   中英

Kotlin 映射/列表可空类型安全

[英]Kotlin Map/List Nullable Type Safety

我是 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)
}
  1. 我不知道为什么这种将mapOf("bar" to null) as Map<String, Int>没有编译错误的工作。
  2. 不知道为什么 function foo在没有编译错误或警告的情况下会导致 NPE 或!!

我确定有类似的问题,但我找不到问题或任何关键词。


实际上我使用这个 map:

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 地图/列表的技巧,以免出现意外错误。

铸造本质上是不安全的。 你告诉编译器你比编译器更了解你正在转换的 object。 在某些情况下,编译器会在转换时给你一个错误,当它可以告诉你正在转换的东西不可能与其他类型匹配时。

当您投射到没有 generics 的类时,您通常根本不会收到任何警告。 假设就像!! 如果你在铸造,你知道你在做什么。 您已经检查了可能的逻辑,并且可以绝对确认强制转换是安全的,即使编译器无法判断。

当您使用 generics 转换为 class 时,编译器至少会给您一个警告。 这是因为如果泛型类型错误,转换不会失败。 由于类型擦除,它会成功,然后当您开始与 object 交互时,您会在代码的其他地方收到错误。 所以出现警告是因为它比 ClassCastException 更糟糕,因为导致的错误发生在代码中的其他地方,而不是执行强制转换的行,这使得调试变得更加困难。

抑制警告只会使警告 go 消失。 它根本不会改变行为。 仅当您检查了警告可能导致的故障并确定您正在执行的操作是安全的时,才取消显示警告。

对于您的 Map,尽管它包含 null 值,但将其转换为不可为空的值将在运行时成功,但稍后在您检索值时失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM