Kotlin `null` 不是 `null`?

Pra*_*ant 1 null kotlin

这看起来有点奇怪,但我不小心用 Kotlin 写了这段代码:

fun exchange(request: Request): ResponseEntity<*> = null!!
Run Code Online (Sandbox Code Playgroud)

IDE 似乎并没有抱怨。允许这样做吗?如果允许,为什么?

Dav*_*idT 5

长话短说

编译器的行为就好像null具有以下类型:

ResponseEntity<*>?
Run Code Online (Sandbox Code Playgroud)

你的 !!然后运算符告诉编译器将运行时强制转换添加到:

ResponseEntity<*>
Run Code Online (Sandbox Code Playgroud)

从编译的角度来看,这是有效的 Kotlin,但在运行时它总是会抛出 NPE。


说明

假设你有代码:

var x : ResponseEntity<*>? = null
var y = x!!
Run Code Online (Sandbox Code Playgroud)

变量 x 已定义为以下类型:

ResponseEntity<*>?
Run Code Online (Sandbox Code Playgroud)

当你使用!! 运算符,您指示编译器返回的类型不可为空,因此变量 y 的类型为:

ResponseEntity<*>
Run Code Online (Sandbox Code Playgroud)

从编译的角度来看,这是有效的代码,但是在运行时它将失败并出现 NullPointerException,这没有什么不寻常的。将这些行合并在一起可以得到:

var z : ResponseEntity<*> = null!!
Run Code Online (Sandbox Code Playgroud)

您可能会争辩说编译器应该警告您此代码可能不正确(这是故意抛出 NPE 的奇怪方式),但它是有效的 Kotlin。

除了我们声明一个变量而不是一个函数(根据您的示例)之外,它编译的原因是相同的。

PS 只是为了好玩;-) - 如果你想要一个简写:throw NullPointerException()你可以这样做:

if (someCondition)
    null!!
Run Code Online (Sandbox Code Playgroud)

  • 轻微的挑剔:编译器不会“推断”“null”的类型。`null` 的类型始终为 `Nothing?`。在此函数中可以返回“null!!”,因为“Nothing”是每种类型的子类型。 (2认同)