21.2 抛出异常
当程序有错误的时候,可以创建一个描述该错误的异常对象,然后使用throw关键字抛出异常对象,抛出的异常对象将被当前代码的更上层代码所捕获,或者不处理直接抛出,或者干脆不予捕获。那么该异常将一直向上传递,直到有人捕获并处理它,如代码清单21-1所示。
代码清单21-1 异常抛出代码示例
public void DoSomething(string para)
{
if(null==para)
{
throw new System.ArgumentException(“data参数不能为空。”);
}
}
在Java语言中,不但有throw关键字,还有一个供方法签名使用的throws关键字,用以标识该方法会抛出哪些异常。在调用该方法的时候,有两个选择:要么提供对这些异常的捕获处理,要么将它们加入方法的throws语句中。当异常触发的时候,就会交由此方法的上层方法去处理,依此类推。要注意的是,C#中并没有类似的机制,也没有提供throws关键字。
我们已经知道了如何抛出异常,那么接下来的问题是,究竟何时应该抛出异常呢?本章的开头已经提到,并非所有情况都要抛出异常,因此,掌握抛出异常的时机也很重要。
在下列情况下一般应抛出异常:
❑方法参数非法。此时应该捕获原始异常,并创建一个System.ArgumentException实例,原始异常应通过ArgumentException的构造函数传给InnerException属性,如代码清单21-2所示。
❑无效的操作。例如,当试图从连接池中获取连接时,因为所有池连接都已被使用,并已达到最大池大小,因此导致超时,从而引发System.InvalidOperationException异常。
❑方法无法完成其定义的功能,例如方法参数为空,或者参数非法,如代码清单21-2所示。
代码清单21-2 方法参数非法示例
///<summary>
///除法运算
///</summary>
///<param name="a">被除数</param>
///<param name="b">除数</param>
///<returns>商</returns>
public long Divide(int a,int b)
{
try
{
return a/b;
}
catch(System.DivideByZeroException e)
{
throw new System.ArgumentException(“除数不能为0!”,"b",e);
}
}