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 中可以是 String
或 String?
。 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.
在我看来,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 中可以是 String
或 String?
。 Android 工作室将String
类型标记为String!
以便您注意并自行设置合适的类型。
Andrei Tanana 的回答描述了一般情况。但特别是对于 LiveData
,请注意 getValue()
(或 Kotlin 中的 value
)可以为空,因此 typed as T?
in Kotlin。所以从某种意义上说,结果是输入 LiveData<String>
还是 LiveData<String?>
并不重要;无论哪种方式,您从中获得的值都是 String?
。
Observer
takes T?
, but this doesn't seem to be reflected in the documentation.