2015-04-20 212 views
22

this article非致死性和異常之間的區別,它說:在斯卡拉

如果你想趕上「一切」,通常會發生,然後使用 非致命性:

import scala.util.control.NonFatal 

try { 
    operation() 
} catch { 
    case NonFatal(e) => errorHandler(e) 
} 

但我通常使用Exception

try { 
    operation() 
} catch { 
    case e: Exception => errorHandler(e) 
} 

我想知道Scala中的NonFatalException有何區別? Scala中的Exception包含致命異常嗎?

java中的AFAIK,Exception用於非致命錯誤,Error用於致命錯誤。是否與java的scala在Exception方面有所不同?

哪種方式是正確的捕捉非致命異常?

回答

23

NonFatal只是這是在scala.util.control定義一個方便的提取:

object NonFatal { 
    /** 
    * Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal 
    */ 
    def apply(t: Throwable): Boolean = t match { 
    case _: StackOverflowError => true // StackOverflowError ok even though it is a VirtualMachineError 
    // VirtualMachineError includes OutOfMemoryError and other fatal errors 
    case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable | _: NotImplementedError => false 
    case _ => true 
    } 
    /** 
    * Returns Some(t) if NonFatal(t) == true, otherwise None 
    */ 
    def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None 
} 

有沒有特殊的「致命的」之類的JVM例外 - Error s爲並不總是「致命的」,他們只是一個特殊的內部例外。 「致命」例外只是NonFatal定義中使用的例外列表。在這個術語中,除InterruptedException之外的所有Exception被認爲是非致命的。考慮InterruptedException是致命的,因爲它意味着線程被中斷,所以如果你想處理它,你應該明確地做到這一點。

NonFatal提取器也正確處理ControlThrowable s。這些例外情況是由breakable內的break等特殊控制轉移功能引發的。

+1

我還不是很清楚,所以'NonFatal'和'Exception'大致相同? – null

+1

沒有。當你在'e:Exception'上匹配時,你正在檢查異常的實際類型,很像Java中的catch(Exception e)'。如果異常是'Exception'的一個子類,那麼異常將被捕獲。另一方面,'NonFatal'是一個提取器對象,它對匹配值執行額外的邏輯。在這種情況下,只有當NonFatal.apply(e)返回true時,NonFatal(e)纔會匹配(並捕獲異常)。當它返回'true'時,你可以在上面的代碼片段中看到。 –

+0

你應該閱讀一些關於提取器的教程,比如[this](http://danielwestheide.com/blog/2012/11/21/the-neophytes-guide-to-scala-part-1-extractors.html),如果你不知道他們是什麼。 –