一個成熟的計算機語言必須有異常機制。併發
爲何呢?ui
由於它能夠幫助開發者們更好的發現bug和解決bug。spa
接下來咱們來看下Dart的異常機制:線程
Dart代碼是支持拋出和捕獲異常的。異常一般是意外狀況發生時的錯誤指示。code
若是異常沒有捕獲,那麼isolate
會接管已經掛起異常,而且一般狀況下isolate
和它程序會被停止。orm
什麼是 isolate ???對象
isolate 是 隔離區 的英文,若是很難理解,咱們不妨把它理解成一個沙盒。內存
大多數計算機,即便在移動平臺上,也有多核CPU。 爲了利用全部這些核心,開發人員傳統上使用併發運行的共享內存線程。 可是,共享狀態併發容易出錯,而且可能致使代碼複雜化。ci
全部Dart代碼都在隔離區運行,而不是線程。 每一個隔離區都有本身的內存堆,確保不會從任何其餘隔離區訪問到本身隔離區的狀態。開發
與Java相比,Dart的全部異常都是未經檢查的異常。 方法不會聲明它們可能引起的異常,而且你不須要捕獲任何異常。
Dart提供了Exception
和Error
類型,以及許多預約義的子類型。 固然,你能夠定義本身的Exception
。 而且Dart程序能夠拋出任何非null對象 (不單單是Exception和Error對象) 做爲異常對象。
下面是拋出或者掛起一個異常的例子:
throw FormatException('Expected at least 1 section');
複製代碼
你也能夠拋出任意對象:
throw 'Out of llamas!';
複製代碼
注意:生產環境質量高的代碼一般會拋出已經實現了的錯誤或異常的類型。
由於拋出異常是一個表達式,因此能夠在=>
語句中以及容許表達式的任何其餘地方拋出異常:
void distanceTo(Point other) => throw UnimplementedError();
複製代碼
捕獲或捕捉異常會中止異常傳遞(除非你從新拋出異常)。 捕獲異常讓你有機會處理它:
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
複製代碼
要處理可能拋出多種類型異常的代碼,能夠指定多個catch子句。 與拋出對象的類型匹配的第一個catch子句處理異常。 若是catch子句未指定類型,則該子句能夠處理任何類型的拋出對象:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e');
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
複製代碼
如前面的代碼所示,你能夠使用on
或catch
或二者。 須要指定異常類型時使用。 在異常處理程序須要異常對象時使用catch
。
你能夠爲catch()
指定一個或兩個參數。 第一個是拋出的異常,第二個是堆棧跟蹤(StackTrace對象)。
try {
// ···
} on Exception catch (e) {
print('Exception details:\n $e');
} catch (e, s) {
print('Exception details:\n $e');
print('Stack trace:\n $s');
}
複製代碼
要部分處理異常,同時容許它傳遞,請使用rethrow
關鍵字。
void misbehave() {
try {
dynamic foo = true;
print(foo++); // Runtime error
} catch (e) {
print('misbehave() partially handled ${e.runtimeType}.');
rethrow; // Allow callers to see the exception.
}
}
void main() {
try {
misbehave();
} catch (e) {
print('main() finished handling ${e.runtimeType}.');
}
}
複製代碼
不管是否拋出異常,要確保某些代碼運行,請使用finally
子句。 若是沒有catch
子句與異常匹配,則在finally
子句運行後傳遞異常:
try {
breedMoreLlamas();
} finally {
// Always clean up, even if an exception is thrown.
cleanLlamaStalls();
}
複製代碼
finally
子句在任何匹配的catch
子句以後運行:
try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}
複製代碼