在本章中,我们将深入探讨 Dart 中的异常处理机制。了解如何使用异常来处理程序运行时可能出现的问题是编写健壮且易于维护代码的关键。
异常的基本概念
异常是指程序运行过程中发生的错误或意外情况,这些情况通常会导致程序无法正常执行。在 Dart 中,异常是一种对象,代表了某种类型的错误或问题。当一个异常被抛出时,如果没有被捕获和处理,程序将终止执行,并显示异常信息。
抛出异常
在 Dart 中,可以使用 throw
关键字来手动抛出一个异常。异常对象通常是继承自 Exception
类的子类实例。例如:
void checkAge(int age) { if (age < 0) { throw Exception("年龄不能为负数"); } }
捕获异常
为了防止程序因未捕获的异常而崩溃,我们需要使用 try-catch
结构来捕获并处理异常。try-catch
结构允许我们在发生异常时提供一种优雅的错误处理方式。例如:
void main() { try { checkAge(-1); } catch (e) { print("捕获到异常:$e"); } }
在这个例子中,如果 checkAge
方法抛出了异常,它会被 catch
块捕获,并打印出相应的异常信息。
自定义异常类
虽然 Dart 提供了一些内置的异常类(如 Exception
和 StateError
),但在某些情况下,我们可能需要创建自己的异常类。这可以通过继承 Dart 的 Exception
类或 Error
类来实现。例如:
// javascriptcn.com 代码示例 class AgeOutOfRangeException implements Exception { final String message; AgeOutOfRangeException(this.message); @override String toString() => "年龄范围异常:$message"; } void checkAge(int age) { if (age < 0 || age > 150) { throw AgeOutOfRangeException("年龄必须在0到150之间"); } } void main() { try { checkAge(160); } catch (e) { print(e.toString()); } }
在这个例子中,我们定义了一个名为 AgeOutOfRangeException
的自定义异常类,并在 checkAge
方法中抛出该异常。当捕获到该异常时,会输出相应的自定义异常信息。
多重捕获
有时候,一个 try
块可能会抛出多种类型的异常。在这种情况下,我们可以使用多个 catch
块来分别处理不同的异常类型。例如:
// javascriptcn.com 代码示例 void main() { try { checkAge(-1); } on StateError catch (e) { print("捕获到 StateError:$e"); } on AgeOutOfRangeException catch (e) { print("捕获到自定义异常:$e"); } catch (e) { print("捕获到其他类型的异常:$e"); } }
在这个例子中,我们使用了多个 catch
块来分别处理 StateError
、自定义异常 AgeOutOfRangeException
以及其他所有类型的异常。
finally 子句
除了 try-catch
结构外,Dart 还支持 finally
子句。无论是否发生异常,finally
子句中的代码都会被执行。这通常用于清理操作,比如关闭文件或释放资源。例如:
// javascriptcn.com 代码示例 void main() { File file; try { file = File('example.txt'); file.writeAsStringSync('Hello, world!'); } finally { file?.deleteSync(); } }
在这个例子中,无论写入文件的操作是否成功,文件最终都会被删除。
总结
通过本章的学习,我们掌握了 Dart 中异常处理的基本概念和方法,包括如何抛出和捕获异常,以及如何使用自定义异常类和多重捕获。此外,我们还了解了 finally
子句的作用,这对于编写健壮的代码非常重要。
接下来,我们将继续深入探索 Dart 的其他高级特性,以便能够构建更复杂和功能丰富的应用程序。