pfe*_*rel 6 casting scala exception
我使用依赖异常的Java库。下面的简化代码:
try {
val eventTime = eventTimeString.as[Date]
} catch {
case e: Exception =>
logger.error(s"Can't parse eventTime from $eventTimeString", e)
// take action for the bad Date string.
}
Run Code Online (Sandbox Code Playgroud)
在Java中,我只捕获将字符串解析为Date的异常,就不会捕获其余的异常,因为它们可能是致命的。我的理解是,捕获Exception意味着捕获任何非致命/非严重的异常。既然不一样,那么抓捕Throwable是安全的,但是真的吗?使用此方法的理由是,未知异常可能从更深的堆栈中抛出,如果它们不是致命的,为什么不捕获所有异常。这一直是Java中的问题,在Java中很容易从您进行的直接调用中找到可能的异常,而从更深层的调用中很难找到。这是Scala解决方案的基本含义,是“捕获所有可恢复的异常”?
我的问题是;是上面的代码被认为是良好的Scala风格,是否“安全”,这比仅捕获Date转换为字符串的字符串要好。
Try@LuisMiguelMejiaSuarez建议解决该问题的样式方面,它提供了一种更惯用的Scala样式,如下所示
Try(eventTimeString.as[Date]) match {
case Success(eventTimeDate) => // work with eventTimeDate
case Failure(e: IllegalArgumentException) => // work with e
case Failure(e: NullPointerException) => // work with e
...
case Failure(e) => // work with e
}
Run Code Online (Sandbox Code Playgroud)
从语法上看,它看起来并没有太大区别,但是从概念上讲,这是一个很大的转变,因为Success和Failure表示常规值,而不是某些例外的控制结构。Success是一个值等7是值,而try-catch更象while或if-else控制设施。
包装可能Try由Java库提供的所有可能引发的库调用,我们可以利用收益糖来像这样链接调用
for {
a <- Try(foo)
b <- Try(bar)
c <- Try(qux)
} yield {
// work with a, b and c
}
Run Code Online (Sandbox Code Playgroud)
哪里
def foo: Int = {
throw new TimeoutException("foo")
42
}
def bar: String = {
throw new IllegalArgumentException("bar")
"hello"
}
def qux: Boolean = {
throw new NullPointerException("qux")
true
}
Run Code Online (Sandbox Code Playgroud)
我们可以按顺序阅读此链,而不必中断我们的思路,并尝试了解一些特殊的控制结构如何适合算法。
关于问题的安全性,可以说,我们不应捕获致命异常,例如LinkageError,并且确实Try与以下异常不匹配
VirtualMachineError
ThreadDeath
InterruptedException
LinkageError
ControlThrowable
Run Code Online (Sandbox Code Playgroud)
如它的构造方式所示
object Try {
def apply[T](r: => T): Try[T] =
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
}
Run Code Online (Sandbox Code Playgroud)
这里NonFatal是
object NonFatal {
def apply(t: Throwable): Boolean = t match {
case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false
case _ => true
}
def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |