前面学习了如何捕获Java运行时由系统引发的异常,如果想在程序中明确地引发异常,则需要用到throw和throws语句。
1、throw语句
throw语句通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行。
throw语句的语法规则如下:
throw ThrowableInstance
其中,ThrowableInstance是Throwable类型或Throwable子类类型的一个对象。通过参数传递到catch子句,或者用new语句来创建一个实例。
案例1:建立ThrowDemo类,使用throw语句抛出异常。
在PCoreUnit4项目新建throwdemo包,在throwdemo包下新建ThrowDemo类。代码如下:
public class ThrowDemo {
/**
* @Title: main
* @Description:Java程序入口main方法
* @param @param args 参数
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
/**
* @Title: demoproc
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param 参数
* @return void 返回类型
* @throws
*/
static void demoproc() {
try {
// 使用throw抛出异常
throw new NullPointerException("这是一个自己抛出的异常");
} catch(NullPointerException e) {
System.out.println("处理自己抛出的异常");
// 再次抛出异常
throw e;
}
}
}在demoproc()方法的try语句块中,使用throw语句抛出一个NullPointerException异常,该异常被demoproc()方法的catch语句捕获,执行catch语句的代码,首先输出“处理自己抛出的异常”语句到控制台,随后再次应用throw语句抛出NullPointerException异常,抛出的异常被main方法的catch语句捕获,输出异常信息。输出结果如下图所示:
语句“throw new NullPointerExceptio()”,用new来构造一个NullPointerException实例。所有的Java内置的运行时异常类有两个构造函数:一个没有参数,一个带有一个字符串参数。当用到第二种形式时,参数指定描述异常的字符串。如果对象用作 print( )或println( )的参数时,该字符串被显示。也可以通过调用gtMessage( )来实现,getMessage( )是由Throwable定义的。
2、throws语句
如果一个方法可以引发异常,而它本身并不对该异常进行处理,那么该方法必须将这个异常抛给调用者可以使程序能够继续执行下去,这时候就要用到throws语句。
throws语句的语法规则如下:
returnType methodName() throws ExceptionType1, ExceptionType2,….
{
//方法体
}在方法体中可以是引发异常列表中的任何一种异常及其子类型的异常。throws用来声明一个方法可能会抛出所有的异常,它跟在方法名称的后面。如果有多个异常,则使用逗号将其分开。调用者调用该方法时,必须要处理这个异常,一般情况下由调用此方法的类来处理。
案例2:建立ThrowsDemo类,使用throws语句抛出异常。
在throwdemo包下新建ThrowsDemo类。代码如下:
public class ThrowsDemo {
/**
* @Title: main
* @Description: Java程序入口main方法
* @param @param args 参数
*
* @return void 返回类型 @throws
*/
public static void main(String[] args) {
try {
testDemo();
} catch (NumberFormatException e) {
System.err.println("非数据类型不能强制类型转换。");
}
}
/**
* @Title: testdemo
* @Description: 方法抛出 NumberFormatException异常
* @param @throws
* NumberFormatException 参数
*
* @return void 返回类型 @throws
*/
public static void testDemo() throws NumberFormatException {
String s = "abc";
System.out.println(Double.parseDouble(s));
}
}如果方法声明后有throws语句,则在此方法被调用时,需要在调用方法中用try和catch进行异常捕获,如果不捕获异常,则需要在调用方法中使用throws语句将异常抛出。
当覆盖抛出异常的方法时,覆盖方法仅需要声明异常的同类或子类。例如,如果父类方法抛出IOException,则覆盖方法可以抛出IOException、FileNotFoundException(IOException的子类),但不可以抛出Exception(IOException的父类)。
3、throw和throws语句的组合应用
在实际应用中,一般都需要throw和throws语句组合应用,就是在捕获异常后,抛出一个明确的异常给调用者。
案例3:新建一个类,在类中添加一个两数相除的方法,方法要求在操作之前必须打印“运算开始”的信息,结束之后必须打印“计算结束”的信息。
在throwdemo包下新建ThrowAndThrowsDemo类。代码如下:
package throwdemo;
/**
* @ClassName: ThrowAndThrowsDemo
* @Description: 异常处理(使用throw和throws 引发异常)案例3
* @author 编程训练营
* @date
*
*/
public class ThrowAndThrowsDemo {
/**
* @Title: main
* @Description: Java程序入口main方法
* @param args 参数
*
* @return void 返回类型 @throws
*/
public static void main(String[] args) {
try {
System.out.println("除法操作:" + div(10, 0));
} catch (Exception e) {
System.out.println("异常产生:" + e);
}
}
/**
* @Title: div
* @Description:计算两数的除法
* @param @param num1
* @param @param num2
* @param @return
* @param @throws Exception 参数
* @return int 返回类型
* @throws
*/
public static int div(int num1,int num2) throws Exception{
// 定义除法操作,如果有异常,则交给被调用处处理
System.out.println("***** 计算开始 *****") ;
int temp = 0 ; // 定义局部变量
try{
// 计算,但是此处有可能出现异常
temp = num1 / num2 ;
}catch(Exception e){
throw e;
}finally{
// 不管是否有异常,都要执行统一出口
System.out.println("***** 计算结束 *****") ;
}
return temp ;
}
}代码中div方法名称后面使用了throws语句抛出Exception异常,main方法是div方法的调用者,因此能够捕获throws语句抛出的异常。finally语句块是不管异常发生与否,都要执行的代码块,下一课会详细讲解。
throw语句是编写在方法之内的,而throws语句是用在方法名称之后的。在同一个方法中使用throw和throws时要注意,throws抛出的类型范围要比throw抛出的对象范围大才可以。