Dart 编程 - 异常



异常(或异常事件)是在程序执行期间出现的问题。当发生异常时,程序的正常流程被打断,程序/应用程序异常终止。

内置的 Dart 异常包括:

序号 异常及描述
1

DeferredLoadException

当延迟加载的库加载失败时抛出。

2

FormatException

当字符串或其他一些数据没有预期的格式并且无法解析或处理时抛出的异常。

3

IntegerDivisionByZeroException

当一个数字除以零时抛出。

4

IOException

所有输入输出相关异常的基类。

5

IsolateSpawnException

当无法创建隔离区时抛出。

6

Timeout

当在等待异步结果时发生计划的超时时抛出。

Dart 中的每个异常都是预定义类Exception的子类型。必须处理异常以防止应用程序突然终止。

try / on / catch 代码块

try 代码块包含可能导致异常的代码。当需要指定异常类型时,使用 on 代码块。当处理程序需要异常对象时,使用catch 代码块。

try 代码块必须后跟一个on / catch 代码块或一个finally 代码块(或两者之一)。当 try 代码块中发生异常时,控制权将转移到catch

处理异常的语法如下所示:

try { 
   // code that might throw an exception 
}  
on Exception1 { 
   // code for handling exception 
}  
catch Exception2 { 
   // code for handling exception 
} 

以下是一些需要记住的要点:

  • 一段代码可以有多个 on / catch 代码块来处理多个异常。

  • on 代码块和 catch 代码块是互斥的,即一个 try 代码块可以同时关联 on 代码块和 catch 代码块。

以下代码演示了 Dart 中的异常处理:

示例:使用 ON 代码块

以下程序将两个分别由变量xy表示的数字相除。该代码抛出异常,因为它尝试除以零。on 代码块包含处理此异常的代码。

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try {
      res = x ~/ y; 
   } 
   on IntegerDivisionByZeroException { 
      print('Cannot divide by zero'); 
   } 
} 

它应该产生以下输出

Cannot divide by zero

示例:使用 catch 代码块

在下面的示例中,我们使用了与上面相同的代码。唯一的区别是catch 代码块(而不是 ON 代码块)包含处理异常的代码。catch 的参数包含在运行时抛出的异常对象。

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try {  
      res = x ~/ y; 
   }  
   catch(e) { 
      print(e); 
   } 
} 

它应该产生以下输出

IntegerDivisionByZeroException

示例:on…catch

以下示例显示了如何使用on...catch 代码块。

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try { 
      res = x ~/ y; 
   }  
   on IntegerDivisionByZeroException catch(e) { 
      print(e); 
   } 
} 

它应该产生以下输出

IntegerDivisionByZeroException

Finally 代码块

finally 代码块包含无论异常是否发生都应执行的代码。可选的finally 代码块在try/on/catch之后无条件执行。

使用finally 代码块的语法如下:

try { 
   // code that might throw an exception 
}  
on Exception1 { 
   // exception handling code 
}  
catch Exception2 { 
   //  exception handling 
}  
finally { 
   // code that should always execute; irrespective of the exception 
}

以下示例说明了finally 代码块的使用。

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try { 
      res = x ~/ y; 
   } 
   on IntegerDivisionByZeroException { 
      print('Cannot divide by zero'); 
   } 
   finally { 
      print('Finally block executed'); 
   } 
}

它应该产生以下输出

Cannot divide by zero 
Finally block executed

抛出异常

throw 关键字用于显式地引发异常。应处理引发的异常以防止程序突然退出。

显式引发异常的语法为:

throw new Exception_name()

示例

以下示例显示了如何使用throw 关键字抛出异常:

main() { 
   try { 
      test_age(-2); 
   } 
   catch(e) { 
      print('Age cannot be negative'); 
   } 
}  
void test_age(int age) { 
   if(age<0) { 
      throw new FormatException(); 
   } 
}

它应该产生以下输出

Age cannot be negative

自定义异常

如上所述,Dart 中的每种异常类型都是内置类Exception的子类型。Dart 通过扩展现有异常来创建自定义异常。定义自定义异常的语法如下所示:

语法:定义异常

class Custom_exception_Name implements Exception { 
   // can contain constructors, variables and methods 
} 

自定义异常应显式引发,并且应在代码中进行处理。

示例

以下示例显示了如何定义和处理自定义异常。

class AmtException implements Exception { 
   String errMsg() => 'Amount should be greater than zero'; 
}  
void main() { 
   try { 
      withdraw_amt(-1); 
   } 
   catch(e) { 
      print(e.errMsg()); 
   }  
   finally { 
      print('Ending requested operation.....'); 
   } 
}  
void withdraw_amt(int amt) { 
   if (amt <= 0) { 
      throw new AmtException(); 
   } 
}  

在上面的代码中,我们定义了一个自定义异常AmtException。如果传递的金额不在预期范围内,则代码会引发此异常。main 函数将函数调用包含在try...catch 代码块中。

该代码应产生以下输出

Amount should be greater than zero 
Ending requested operation.... 
广告