異常
您的Dart代碼可以拋出并捕獲異常。異常是表示發(fā)生了意外的錯(cuò)誤。如果沒(méi)有捕獲異常,引發(fā)異常的隔離程序?qū)⒈粧炱?,及其程序?qū)⒈唤K止。
與Java相反,Dart的所有異常都是未檢查的異常。方法不聲明它們可能拋出哪些異常,也不需要捕獲任何異常。
Dart提供了異常和錯(cuò)誤類(lèi)型以及許多預(yù)定義的子類(lèi)型。當(dāng)然,您可以定義自己的異常。然而,Dart程序可以拋出任何非空對(duì)象 —不僅僅是異常和錯(cuò)誤對(duì)象— 作為異常。
Throw
下面是一個(gè)拋出或引發(fā)異常的例子:
throw FormatException('Expected at least 1 section');
你也可以拋出任意對(duì)象:
throw 'Out of llamas!';
注意:產(chǎn)品質(zhì)量代碼通常會(huì)拋出實(shí)現(xiàn)錯(cuò)誤或異常的類(lèi)型。
因?yàn)閽伋霎惓J且粋€(gè)表達(dá)式,所以可以在=>語(yǔ)句中拋出異常,也可以在任何允許表達(dá)式的地方拋出異常:
void distanceTo(Point other) => throw UnimplementedError();
Catch
要處理可以拋出多種類(lèi)型異常的代碼,可以指定多個(gè)catch子句。匹配被拋出對(duì)象類(lèi)型的第一個(gè)catch子句處理異常。如果catch子句沒(méi)有指定類(lèi)型,該子句可以處理任何類(lèi)型的拋出對(duì)象:
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或兩者都使用。在需要指定異常類(lèi)型時(shí)使用on。在異常處理程序需要異常對(duì)象時(shí)使用catch。
您可以指定一個(gè)或兩個(gè)參數(shù)來(lái)catch()。第一個(gè)是拋出的異常,第二個(gè)是堆棧跟蹤(StackTrace對(duì)象)。
try {
// ···
} on Exception catch (e) {
print('Exception details:\n $e');
} catch (e, s) {
print('Exception details:\n $e');
print('Stack trace:\n $s');
}
要部分處理異常,同時(shí)允許它傳播,請(qǐng)使用rethrow關(guān)鍵字。
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
要確保某些代碼能夠運(yùn)行,無(wú)論是否拋出異常,請(qǐng)使用finally子句。如果沒(méi)有catch子句匹配異常,則異常在finally子句運(yùn)行后傳播:
try {
breedMoreLlamas();
} finally {
// Always clean up, even if an exception is thrown.
cleanLlamaStalls();
}
finally語(yǔ)句在任何匹配的catch子句后運(yùn)行:
try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}