目录

Flutter-Dart-异常处理全面解析

Flutter Dart 异常处理全面解析

引言

在 Flutter 开发中,使用 Dart 语言进行编程时,异常处理是至关重要的一环。异常是程序在运行过程中出现的错误或意外情况,若不进行妥善处理,可能会导致程序崩溃。本文将详细介绍 Dart 中的异常处理机制,包括异常的抛出、捕获以及不同类型的异常,并结合代码示例进行说明。

1. 异常概述

在 Dart 中,异常是指程序在执行过程中遇到的错误情况。当出现异常时,程序的正常执行流程会被打断,若没有合适的异常处理机制,程序就会崩溃。Dart 中的异常可以是预定义的异常类型,也可以是自定义的异常类型。

2. 抛出异常

在 Dart 中,可以使用 throw 关键字来抛出异常。 throw 后面可以跟任何对象,但通常会抛出一个继承自 ExceptionError 的对象。

代码示例

void divide(int a, int b) {
  if (b == 0) {
    throw Exception('除数不能为零');
  }
  print('结果: ${a / b}');
}

void main() {
  divide(10, 0);
}

代码解释

  • 定义了一个 divide 函数,用于计算两个整数的除法。
  • 在函数内部,检查除数 b 是否为零。如果为零,则使用 throw 关键字抛出一个 Exception 对象,并附带错误信息 '除数不能为零'
  • main 函数中调用 divide(10, 0) ,由于除数为零,会抛出异常,程序会终止执行。

3. 捕获异常

为了避免程序因异常而崩溃,可以使用 try - catch 语句来捕获并处理异常。

代码示例

void divide(int a, int b) {
  if (b == 0) {
    throw Exception('除数不能为零');
  }
  print('结果: ${a / b}');
}

void main() {
  try {
    divide(10, 0);
  } catch (e) {
    print('捕获到异常: $e');
  }
  print('程序继续执行');
}

代码解释

  • main 函数中,使用 try 块包裹可能会抛出异常的代码 divide(10, 0)
  • 如果 try 块中的代码抛出异常,程序会立即跳转到 catch 块中执行。
  • catch 块中的参数 e 表示捕获到的异常对象,通过 print('捕获到异常: $e'); 可以将异常信息输出。
  • 由于异常被捕获并处理,程序会继续执行 catch 块后面的代码 print('程序继续执行');

捕获特定类型的异常

可以在 catch 语句中指定要捕获的异常类型,这样可以针对不同类型的异常进行不同的处理。

void divide(int a, int b) {
  if (b == 0) {
    throw ArgumentError('除数不能为零');
  }
  print('结果: ${a / b}');
}

void main() {
  try {
    divide(10, 0);
  } on ArgumentError catch (e) {
    print('捕获到参数错误异常: ${e.message}');
  } catch (e) {
    print('捕获到其他异常: $e');
  }
}

代码解释

  • divide 函数中,抛出了一个 ArgumentError 类型的异常。
  • main 函数的 try - catch 语句中,首先使用 on ArgumentError catch (e) 来捕获 ArgumentError 类型的异常,并输出异常信息。
  • 如果捕获到的异常不是 ArgumentError 类型,则会被第二个 catch 块捕获并处理。

4. finally 语句

finally 语句用于定义无论是否发生异常都会执行的代码块。通常用于释放资源,如关闭文件、网络连接等。

代码示例

void divide(int a, int b) {
  if (b == 0) {
    throw Exception('除数不能为零');
  }
  print('结果: ${a / b}');
}

void main() {
  try {
    divide(10, 0);
  } catch (e) {
    print('捕获到异常: $e');
  } finally {
    print('无论是否发生异常,这里的代码都会执行');
  }
}

代码解释

  • try - catch 语句中添加了 finally 块。
  • 无论 try 块中的代码是否抛出异常, finally 块中的代码 print('无论是否发生异常,这里的代码都会执行'); 都会被执行。

5. 自定义异常

除了使用 Dart 预定义的异常类型,还可以自定义异常类来满足特定的需求。

代码示例

// 自定义异常类
class CustomException implements Exception {
  final String message;

  CustomException(this.message);

  @override
  String toString() {
    return 'CustomException: $message';
  }
}

void checkNumber(int number) {
  if (number < 0) {
    throw CustomException('数字不能为负数');
  }
  print('数字合法: $number');
}

void main() {
  try {
    checkNumber(-5);
  } catch (e) {
    if (e is CustomException) {
      print('捕获到自定义异常: ${e.message}');
    } else {
      print('捕获到其他异常: $e');
    }
  }
}

代码解释

  • 定义了一个自定义异常类 CustomException ,它实现了 Exception 接口,并包含一个 message 字段用于存储异常信息。
  • 重写了 toString 方法,以便在输出异常信息时能更清晰地显示。
  • checkNumber 函数中,检查传入的数字是否为负数,如果是,则抛出 CustomException 异常。
  • main 函数的 try - catch 语句中,捕获异常并判断是否为 CustomException 类型,然后进行相应的处理。

6. rethrow 关键字

rethrow 关键字用于在捕获异常后重新抛出该异常,通常用于在处理部分异常信息后,将异常传递给调用者继续处理。

代码示例

void divide(int a, int b) {
  if (b == 0) {
    throw Exception('除数不能为零');
  }
  print('结果: ${a / b}');
}

void wrapperFunction() {
  try {
    divide(10, 0);
  } catch (e) {
    print('在 wrapperFunction 中捕获到异常: $e');
    rethrow;
  }
}

void main() {
  try {
    wrapperFunction();
  } catch (e) {
    print('在 main 函数中捕获到重新抛出的异常: $e');
  }
}

代码解释

  • wrapperFunction 中,使用 try - catch 语句捕获 divide 函数抛出的异常,并输出异常信息。
  • 使用 rethrow 关键字将捕获到的异常重新抛出。
  • main 函数中,再次捕获重新抛出的异常并输出异常信息。

总结

Dart 中的异常处理机制提供了强大的工具来应对程序运行过程中出现的错误情况。通过合理使用 throwtry - catchfinally 、自定义异常和 rethrow 等特性,可以使程序更加健壮,避免因异常而崩溃。在实际开发中,应根据具体的业务需求和场景,选择合适的异常处理方式。