Kotlin 的安全转换(或在此上下文中 "unsafe"-转换)隐藏了 Android Studio 可能发出的 NullPointerException 警告
Kotlin's safe-cast (or in this context "unsafe"-cast) hides possible NullPointerException warning by Android Studio
当使用 Java 在 AS 中开发时,下面一行显示 toggleSoftInput
可能产生 NPE 的警告。如果您忘记了 NPE 检查,这将非常有用。
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(....);
但是对于 Kotlin,这就成了一个问题。使用 as
进行转换意味着 IDE 不会费心去检查 toggleSoftInput()
是否会产生 NPE,因为 as
隐含地暗示着。
val imm = mContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput()
一旦我使用安全转换 as?
,IDE 会警告我对 imm
进行安全调用,因为它可能是 null
.
一般问题:如果开发人员忘记安全转换怎么办,Kotlin 的安全转换是否会隐式地杀死 IDE 用户友好的功能,或者我遗漏了什么?
具体问题: 除了不要忘记安全投射之外,是否有任何可能的方法来解决这些问题? :)
遗憾的是这个具体方法:
context.getSystemService(@NonNull String name)
非常旧 API,这是它的缺陷之一 - 它 returns 一个 Object
未指定类型和可空性,所以除了执行 unsafe/safe 转换别无他法.
您几乎没有更新的替代方案可以为您提供安全的可为 null 的服务 class 对象:
// available since API 23:
val ims23 = context.getSystemService(InputMethodManager::class.java)
// available in androidx.core
val imsCompat = ContextCompat.getSystemService(context, InputMethodManager::class.java)
// available in androidx.core:core-ktx
val imsKtx = context.getSystemService<InputMethodManager>()
当使用 Java 在 AS 中开发时,下面一行显示 toggleSoftInput
可能产生 NPE 的警告。如果您忘记了 NPE 检查,这将非常有用。
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(....);
但是对于 Kotlin,这就成了一个问题。使用 as
进行转换意味着 IDE 不会费心去检查 toggleSoftInput()
是否会产生 NPE,因为 as
隐含地暗示着。
val imm = mContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput()
一旦我使用安全转换 as?
,IDE 会警告我对 imm
进行安全调用,因为它可能是 null
.
一般问题:如果开发人员忘记安全转换怎么办,Kotlin 的安全转换是否会隐式地杀死 IDE 用户友好的功能,或者我遗漏了什么?
具体问题: 除了不要忘记安全投射之外,是否有任何可能的方法来解决这些问题? :)
遗憾的是这个具体方法:
context.getSystemService(@NonNull String name)
非常旧 API,这是它的缺陷之一 - 它 returns 一个 Object
未指定类型和可空性,所以除了执行 unsafe/safe 转换别无他法.
您几乎没有更新的替代方案可以为您提供安全的可为 null 的服务 class 对象:
// available since API 23:
val ims23 = context.getSystemService(InputMethodManager::class.java)
// available in androidx.core
val imsCompat = ContextCompat.getSystemService(context, InputMethodManager::class.java)
// available in androidx.core:core-ktx
val imsKtx = context.getSystemService<InputMethodManager>()