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)]{
...
}

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

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’.