• 和java不同,dart中的异常都是非检查异常,方法可以不声明可能抛出的异常,也不要求捕获任何异常。
  • dart 提供了 Exception 和 Error 类型以及一些子类型来定义异常。不过,还可以自定义异常,只要抛出非空对象作为异常即可,不要求必须是 Exception 和 Error 对象,一般来说都是抛出 Exception 和 Error 类型。
  • Throw

    //抛出内置类型异常 FormatException
    throw FormatException('Expected at least 1 section');
    //抛出任意类作为异常
    throw 'Out of llamas!';
    

    throw 语句是一个表达式,如果方法体只有throw语句时,可以使用箭头语法。

    void distanceTo(Point other) => throw UnimplementedError();
    

    Catch

    异常捕获用来终止异常的传递(rethrow除外)并对其进行处理。

    try {
      breedMoreLlamas();
    } on OutOfLlamasException {
      buyMoreLlamas();
    

    如果需要处理多种类型的异常,可以定义多个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 语句中的代码执行完毕后,异常再抛出。

    finally 语句位于其他 catch 语句之后。

    try {
      breedMoreLlamas();
    } finally {
      // Always clean up, even if an exception is thrown.
      cleanLlamaStalls();
    try {
      breedMoreLlamas();
    } catch (e) {
      print('Error: $e'); // Handle the exception first.
    } finally {
      cleanLlamaStalls(); // Then clean up.