异常是指一些未知的错误情况。Dart 代码可以抛出和捕获异常。 如果异常没有被捕获, 则异常会抛出,抛出异常的代码终止执行。
Dart中不同于Java的是所有异常是非检查异常。 方法不会声明它们抛出的异常,也不要求捕获任何异常。
Dart 提供了 Exception 和 Error 类型,还有一些子类型。也可以定义自己的异常类型。 但是,此外 Dart 程序可以抛出任何非 null 对象, 不仅限 Exception 和 Error 对象。
throw
下面是关于抛出或者 引发 异常的示例:
throw FormatException('Expected at least 1 section');
也可以抛出任意的对象:
throw 'Out of llamas!';
提示: 高质量的生产环境代码通常会实现 Error 或 Exception 类型的异常抛出。
因为抛出异常是一个表达式, 所以可以在 => 语句中使用,也可以在其他使用表达式的地方抛出异常:
void distanceTo(Point other) => throw UnimplementedError();
catch
捕获异常的机会来处理该异常;捕获异常避免异常继续传递(除非重新抛出( rethrow )异常):
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
可以指定多个 catch 语句,处理可能抛出多种类型异常的代码。 与抛出异常类型匹配的第一个 catch 语句处理异常。 如果 catch 语句未指定类型, 则该语句可以处理任何类型的抛出对象:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 一个特殊的异常
buyMoreLlamas();
} on Exception catch (e) {
// 其他任何异常
print('Unknown exception: $e');
} catch (e) {
// 没有指定的类型,处理所有异常
print('Something really unknown: $e');
}
如上所示, on 和 catch可以在捕获语句中同时使用 ,也可以单独分开使用。 使用 on 来指定异常类型, 使用 catch 来 捕获异常对象。
catch() 函数可以指定1到2个参数, 第一个参数为抛出的异常对象, 第二个为堆栈信息 ( 一个 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();
}
任何匹配的 catch 执行完成后,再执行 finally :
try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}