1

下面的代码片段来自我的 onOptionsItemSelected 函数。下面的第 2-5 行假设在显示软键盘时隐藏软键盘,否则调用活动的完成功能。

我从堆栈溢出时“如何隐藏软键盘”的答案之一中获得了这段代码。它在我的手机上运行良好,但是当我最近在 Playstore 上提交我的应用程序进行内部测试时,我发现它有时会抛出 NPE。有人可以解释为什么会发生这种情况的逻辑吗?

R.id.done -> { 
  val view:View? = this.currentFocus!! // throws null pointer exception
  val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 
  if (bool && view!=null) { 
    imm.hideSoftInputFromWindow(view.windowToken, 0) 
  } else{ 
    finish() 
  } 
  return true 
4

3 回答 3

2

!!运算符称为非空断言运算符- 如果currentFocus为空,它将抛出 NPE。由于您的viewcan be null,因此删除!!操作员是安全的。

读:

于 2018-07-30T08:32:34.847 回答
1

您确定您清楚地了解!!操作员的工作原理吗?如果this.currentFocus为空,则表明它应该抛出一个空指针异常: https ://kotlinlang.org/docs/reference/null-safety.html

删除!!,它应该工作得更好。

于 2018-07-30T08:31:58.147 回答
0

运算符的重点!!是将可为空类型的值转换为不可为空的等价物,同时积极确保该值确实不为空(否则抛出 NPE)。

这是您的代码实际执行的操作:

val nonNullView: View = this.currentFocus!! // crashes if null
val view: View? = nonNullView

如您所见,!!如果值为空,则必须抛出异常,因为空值不能是类型View(不可为空)。

在您的情况下,无论如何您最终都会得到一个可为空的类型View?,因此您不需要 施加的额外临时限制!!,因此您不妨将其删除:

val view: View? = this.currentFocus
于 2018-07-30T13:51:54.700 回答