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);

}

}