我对从以下代码片段获取的NPE感到困惑:

import sys.process._
val context = ExecutionContext.Implicits.global
val fr = Future {
  Seq("sudo", "sh", "-c", cmd).! // some command line command
}(context)
try {
  if (fr == null) {
    println("was null")
  } else {
    println("was not null")
  }
  fr.onComplete(t => println("hello"))
} catch {
  case e: Throwable => println(s"caught: $e")
}


输出:

was not null
caught: java.lang.NullPointerException


编辑:我知道为什么现在有NPE。我需要向onComplete隐式或显式提供执行上下文。我不明白的是为什么这段代码会这样编译:


如果我像fr.onComplete(t => println("hello"))(context)中那样手动提供上下文,则代码将按预期工作。
如果声明implicit val context = ExecutionContext.Implicits.global,则会出现编译错误(找不到onComplete的隐式执行上下文)。为什么这不能解决问题?
如果更改为import ExecutionContext.Implicits.global,则onComplete会编译,但是Future { Seq...}会抱怨缺少执行上下文(当然,在删除显式传递的执行上下文之后)。


有人对此有任何意义吗?

最佳答案

似乎onComplete可能选择了与您想要的有所不同的隐式ExecutionContext,并且该隐式上下文为null。这有相同的效果吗?

import sys.process._
val context = ExecutionContext.Implicits.global
val fr = Future {
  Seq("sudo", "sh", "-c", cmd).! // some command line command
}(context)
try {
  if (fr == null) {
    println("was null")
  } else {
    println("was not null")
  }
  fr.onComplete(t => println("hello"))(context)
} catch {
  case e: Throwable => println(s"caught: $e")
}


还是这个呢?

import sys.process._
implicit val context = ExecutionContext.Implicits.global
val fr = Future {
  Seq("sudo", "sh", "-c", cmd).! // some command line command
}
try {
  if (fr == null) {
    println("was null")
  } else {
    println("was not null")
  }
  fr.onComplete(t => println("hello"))
} catch {
  case e: Throwable => println(s"caught: $e")
}

关于scala - 在什么情况下非null的将来f可以在'f.onComplete(x => println(“hello”)))上抛出NullPointerException?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24193245/

10-10 10:39