Kotlin 中的 LiveData null 安全吗?为什么Android Studio可以编译呢?

Is LiveData null safe in Kotlin? Why can Android Studio compile it?

在我看来,Kotlin 是 null 安全的。

代码A来自项目Universal Android Music Player Sample,可以参考here

似乎val rootMediaId: LiveData<String>在代码A中不是null安全的,一个null字符串可以分配给rootMediaId,我不知道为什么AndroidStudio可以编译这些代码, 你能告诉我吗?

我认为代码 B 是有信誉的代码。

代码A

viewModel.rootMediaId.observe(this,
                Observer<String> { rootMediaId ->
                    if (rootMediaId != null) {
                        navigateToMediaItem(rootMediaId)
                    }
                })



class MainActivityViewModel(
    private val musicServiceConnection: MusicServiceConnection
) : ViewModel() {

    val rootMediaId: LiveData<String> =
        Transformations.map(musicServiceConnection.isConnected) { isConnected ->
            if (isConnected) {
                musicServiceConnection.rootMediaId
            } else {
                null
            }
        }
   ...
}

代码B

class MainActivityViewModel(
    private val musicServiceConnection: MusicServiceConnection
) : ViewModel() {

    val rootMediaId: LiveData<String?> =
        Transformations.map(musicServiceConnection.isConnected) { isConnected ->
            if (isConnected) {
                musicServiceConnection.rootMediaId
            } else {
                null
            }
        }
   ...
}

因为 Live Data 是用 Java 写的,所以 Kotlin 在这里使用平台类型。您可以阅读更多相关信息 here。两个词:Java 类型不包含可空性信息,因此 Kolin 无法推断出正确的类型。 Java 中的 String 在 Kotlin 中可以是 StringString?。 Android 工作室将String 类型标记为String! 以便您注意并自行设置合适的类型。

Andrei Tanana 的回答描述了一般情况。但特别是对于 LiveData,请注意 getValue()(或 Kotlin 中的 value)可以为空,因此 typed as T? in Kotlin。所以从某种意义上说,结果是输入 LiveData<String> 还是 LiveData<String?> 并不重要;无论哪种方式,您从中获得的值都是 String?

also states Observer takes T?, but this doesn't seem to be reflected in the documentation.