4.1 异常 – 《简单易懂的Dart》

4.1.1 抛出异常

在Dart中抛出异常使用关键字throw.

异常是一个对象,所有异常都继承自Exception,另外,throw不仅可以抛出异常对象,还可以抛出字符串等其他对象.

void main() {
  throw new Exception('Error');
}

上面这段代码抛出了一个Exception对象,其内容为Error.

抛出字符串等其他对象:

void main() {
  throw 'Error';
}

运行程序,抛出字符串”Error”.

4.1.2 捕获异常

在Dart中捕获异常使用try…on…catch的组合,其中on和catch可以在一定条件下省略:

                                                                                    try{
                                                                                    ...
                                                                                    }[on Exception] [catch(e)]{
                                                                                    ...
                                                                                    }
                                                                                    ``` 

                                                                                    下面这段代码可以帮助我们加以区分这三种异常捕获类型.

                                                                                    ```dart
                                                                                    void main() {
                                                                                      try{
                                                                                        print(100~/0);
                                                                                      }on IntegerDivisionByZeroException{
                                                                                        print('IntegerDivisionByZeroException');
                                                                                      }on Exception catch(e){
                                                                                        print('$e');
                                                                                      }catch(e){
                                                                                        print('Type:$e');
                                                                                      }
                                                                                    }

这段代码的输出结果为:

IntegerDivisionByZeroException

首先try{}中是我们运行的代码,在try{}中抛出的异常将会被try{}后面的结构捕获.

我们在try中写了100~/0,这是一个整数除零的运算,将会抛出整数除零异常(IntegerDivisionByZeroException).

我们将try{]中的内容修改为

throw new Exception('Error!!!');

运行程序,输出结果为:

Exception: Error!!!

由于new Exception(‘Error!!!’)不是IntegerDivisionByZeroException异常,所以并没有被on IntegerDivisionByZeroException捕获.

因为new Exception(‘Error!!!’)是Exception类的实例,所以在进入on Exception catch(e)时被捕获,输出捕获到的e的内容.

再将try{}中的内容修改为

throw 'Error';

运行程序,输出结果为:

Type:Error

因为’Error’是从String类型,所以无法被前两个Exception异常捕获.

catch(e)捕获所有throw抛出的对象,无论是否是Exception对象,’Error’最终被catch(e)捕获.

4.1.3 finally

finally块中的代码会在try块中的异常未被捕获时执行,如果try块中存在未被捕获的异常,那么该异常将在finally块中的代码执行完毕后被抛至上一代码块(如果始终没有捕获,则抛至顶级,导致编译报异常).

void main() {
  try{
    throw 'Error';
  }on IntegerDivisionByZeroException{
    print('IntegerDivisionByZeroException');
  }on Exception catch(e){
    print('$e');
  }finally{
    print('Not caught');
  }
}

这段代码由于没有捕获throw ‘Error’,所以将会执行print(‘Not caught’),在屏幕上打印Not caught.

之后’Error’将会被抛至顶级,程序报异常.

4.1.4 异常嵌套处理

上一节中的’Error’被抛到顶级,导致了程序报异常,显然这不是我们想见到的.

我们可以在throw ‘Error’外嵌套一层try…catch结构,捕获’Error':

void main() {
  try{
    try{
      throw 'Error';
    }on IntegerDivisionByZeroException{
      print('IntegerDivisionByZeroException');
    }on Exception catch(e){
      print('$e');
    }finally{
      print('Not caught');
    }
  }catch(e){
    print('Type:$e');
  }
}

运行程序,输出结果为:

Not caught
Type:Error

可见嵌套在外层的catch(e)成功捕获了’Error’.