异常指定的是代码运行中意外发生的错误事件,在Dart中你可以抛出或者捕获异常,如果异常没有被捕获,应用程序将会终止。与java相比,所有Dart异常都是没被终止的,可以继续传递,一般情况下所有方法都不会声明抛出的异常,需要自己手动捕获

Dart提供异常和错误的类型以及预定义的子类,当然你也可以预定义自己的异常子类。Dart允许抛出任意类型的非空对象作为一个异常

throw

throw FormatException('Expected at least 1 section');

直接将一个字符串作为异常抛出

throw 'Out of llamas!';

虽然Dart直接抛出任意类型的非空对象作为异常,但在Dart高效编程中一般建议继承Error 或者 Exception类作为子类实现错误或者异常的抛出。

使用Dart内置的Exception或者Error,来实现一个异常的掏出

import 'dart:core';

class AppException implements Exception {
  final message;
  AppException([this.message]);
}

class AppError extends Error {
  AppError();
}

main(List<String> args) {
  // throw AppError();
  // throw AppException('这是一个异常');
}

catch

捕获异常会阻止异常传递,除非你重新抛出异常,或者使用rethrow关键词让异常传递下去

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

可以使用on处理指定的异常类型,也可以将on使用多次处理不同类型的异常,在最后catch里可以传递第二个参数来获得堆栈信息

 try {
    throw AppException('这是一个异常');
  } on String {
    print('处理字符串类型');
  } on AppException {
    print('AppException');
  } on Exception catch (e) {
    print('未知异常: $e');
  }catch(e,s){
    print('处理所有类型的异常');
  }

当我们在自己函数内部做了异常处理后,但又想让调用者看到原始的异常的信息(这意味我们不能继续抛出异常,否则当前的异常就无法传递),可以使用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,让程序继续运行

try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // 先处理异常.
} finally {
  cleanLlamaStalls(); // 终止异常
}