Dart代码可以抛出并捕获异常。异常是表示发生了意外的错误。如果没有捕获异常,引发异常的隔离程序将被挂起,通常隔离程序及其程序将被终止。
与Java相反,Dart的所有异常都是未检查的异常。方法不会声明它们可能抛出哪些异常,也不需要捕获任何异常。
Dart提供了Exception
和Error
类型以及许多预定义的子类型。当然,您可以定义自己的异常。然而,Dart程序可以抛出任何非空对象(不仅仅是 Exception
和Error
对象)作为异常。
Throw
下面是一个抛出或引发异常的例子:
throw FormatException('Expected at least 1 section');
你也可以抛出任意对象:
throw 'Out of llamas!';
提示:Production-quality code
通常会抛出实现Exception
和Error
的类型。
因为抛出异常是一个表达式,所以可以在=>语句中抛出异常,也可以在任何允许表达式的地方抛出异常:
void distanceTo(Point other) => throw UnimplementedError();
Catch
捕获异常将阻止异常传播(除非重新抛出异常)。捕获异常给您一个处理它的机会:
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
或两者都使用。在需要指定异常类型时使用on
。在异常处理程序需要异常对象时使用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
要确保某些代码能够运行,无论是否抛出异常,请使用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.
}