为什么HashMap.get不返回可空类型?

时间:2015-04-19 15:54:09

标签: nullpointerexception null kotlin java-collections-api java-interop

以下示例抛出NullPointerException

,我感到有些惊讶
fun main(args: Array<String>) {
    val hm = HashMap<String, Int>()
    hm.put("alice", 42)
    val x = hm.get("bob")
    println(x)   // BOOM
}

我认为Kotlin代码中没有NullPointerException

如果我使用可选类型对x进行注释,则程序会打印null而不是:

fun main(args: Array<String>) {
    val hm = HashMap<String, Int>()
    hm.put("alice", 42)
    val x: Int? = hm.get("bob")
    println(x)   // null
}

我是否发现了一个特例,或者这是Kotlin / Java互操作的一般问题?

我正在使用带有Kotlin 0.11.91.1插件的IntelliJ IDEA 14.1社区版。

2 个答案:

答案 0 :(得分:6)

您的变量hm属于HashMap类型,因为它是一个平台类,其方法返回platform types。然而,Kotlin自己的Map及其子路径子接口MutableMap会返回get()的可空类型。

将您的代码更改为

val hm : MutableMap<String, Int> = HashMap()

它将打印&#34; null&#34;。

答案 1 :(得分:0)

这不再是问题。 Kotlin对如何注释JDK类有一个问题,告诉它如何处理一些方法。目前Kotlin没有出现您所看到的问题。

这两个都从Java集合中返回HashMap,第一个hm1更具惯用性。

val hm1 = hashMapOf<String, Int>()
val hm2 = HashMap<String, Int>()

如果提前知道这些值,您也可以将其创建为已有值的地图。

val hm3 = hashMapOf("alice" to 42)

或只读版本:

val hm4 = mapOf("alice" to 42)

在所有这些版本中,当调用具有未知值的null并打印结果时,它们都会打印get()

println(hm1.get("missing"))
println(hm2.get("missing"))
println(hm3.get("missing"))
println(hm4.get("missing"))

所有get()都有相同的签名,因为Kotlin团队注释了JDK类,知道get()在这种情况下返回可以为空的值Int?

这些注释中只有错误才会导致问题。如果你在JDK运行时库中看到另一个,那么应该是tracked as a bug