📄 java06_05.htm
字号:
<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Java程序设计</title>
</head>
<body background="Bg.gif">
<p align="center"><font size="5"><b>§6.5 抛出异常</b></font></p>
<p align="left">
用户如果需要,也可以自己抛出异常。被抛出的异常对象既可以是系统定义的异常类,也可以是用户自己定义的新的异常类。一般格式如下:</p>
<p align="center"><b>throw 异常对象名; </b>或者<b> throw new
异常类名();</b></p>
<p align="left">两种形式本质上是一样的。第一种形式需要先构造异常对象,因而较少用到,实际编程中都是用的第二种形式。</p>
<p align="left"> 一条throw语句一旦被执行,程序立即转入相应的异常处理程序段,它后面的语句就不再执行了(这一点类似于return语句),而且它所在的方法也不再返回有意义的值。一个方法中,throw语句可以有多条,但每一次最多只能执行其中的一条。一般情况下,throw语句都会写在判断语句块中,以避免每次都执行该语句。下面是一个简单的例子:</p>
<p align="left">class MyException{<br>
public static void main(String argv[])<br>
{ double a=Math.random();<br>
try{ <br>
if (a>0.5)<br>
System.out.println(a);<br>
else<br>
throw new Exception(); //抛出异常<br>
}<br>
catch (Exception el){<br>
System.out.println(el.toString()); //输出异常对象的一些信息<br>
} <br>
}<br>
}</p>
<p align="left">注意这里是由main()自己抛出异常,并由自己来捕获的。如果改成下面这个样子:</p>
<p align="left">class MyException{<br>
public static void main(String argv[]){<br>
double a=Math.random();<br>
if (a>0.5)<br>
System.out.println(a);<br>
else<br>
throw new Exception();
//抛出异常<br>
}<br>
}</p>
<p align="left">则编译的时候会提示说:<br>
未报告的异常 java.lang.Exception ;必须被捕获或被声明抛出<br>
throw new Exception(); <br>
^<br>
1 个错误</p>
<p align="left">也就是说,一个方法中如果使用throw来抛出异常,要么自己捕获它,要么声明抛出了一个异常。要声明抛出了异常,需要用<b>throws</b>关键字在方法的头部声明,格式如下:</p>
<p align="left"> [修饰符][返回类型]
方法名(参数表)<b>throws 异常类名1[,异常类名2[,...]]</b></p>
<p align="left">我们先来看下面这个例子:</p>
<p align="left">class MyException{<br>
public static void main(String argv[]){<br>
try{ //由于CreateException会抛出异常,所以编译器会强制程序员在此捕获异常<br>
CreateException();<br>
}<br>
catch(Exception e){<br>
System.out.println("这是在main内捕获的异常:"+e);<br>
} <br>
}<br>
public static void CreateException() <b> throws Exception</b>{
//在这里声明要抛出的异常<br>
double a=Math.random();<br>
if (a>0.5)<br>
System.out.println(a);<br>
else<br>
throw new Exception(); <br>
} <br>
}</p>
<p align="left">
在这里我们可以看到,捕获自己抛出的异常和捕获系统类抛出的异常并没有什么区别。在CreateException()中,我们即使用throws声明要抛出异常,也仍然可以在此方法中先捕获异常,像下面这个样子:</p>
<p align="left">class MyException{<br>
public static void main(String argv[]){<br>
try{<br>
CreateException();<br>
}<br>
catch(Exception e){<br>
System.out.println("这是在main内捕获的异常:"+e);<br>
} <br>
}<br>
public static void CreateException() <b> throws Exception</b>{ //在这里声明要抛出的异常<br>
double a=Math.random();<br>
try{<br>
if (a>0.5)<br>
System.out.println(a);<br>
else<br>
throw new Exception(); <br>
}<br>
catch(Exception e){<br>
System.out.println("这是在CreateException内捕获的异常:"+e);<br>
} <br>
} <br>
}</p>
<p align="left">
这么写并没有什么语法错误,但问题是,一旦异常发生,首先捕获它的是CreateException方法中的catch语句,而main方法中的catch再也无法捕获到此异常,也就永远不会运行其中的语句,所以输出结果总是:<i>这是在CreateException内捕获的异常:java.lang.Exception</i></p>
<p align="left">
一般情况下我们当然不会写成上面这个样子,但在某些特殊情况下,我们可能要在catch语句中再次抛出异常,这称为“再引发”。这就使得抛出异常的方法自己可以对异常进行一些前期处理,而将一些善后工作交由调用者来处理。下面是上例的改进:</p>
<p align="left"> public static void CreateException() <b> throws Exception</b>{
//在这里声明要抛出的异常<br>
double a=Math.random();<br>
try{<br>
if (a>0.5)<br>
System.out.println(a);<br>
else<br>
throw new Exception(); <br>
}<br>
catch(Exception e){<br>
System.out.println("这是在CreateException内捕获的异常:"+e);<br>
throw e; //再次抛出异常<br>
} <br>
}</p>
<p align="left">输出的结果是:<br>
<i>这是在CreateException内捕获的异常:java.lang.Exception<br>
这是在main内捕获的异常:java.lang.Exception</i></p>
<p align="left"> 如果一个方法中用throw抛出了不止一种异常,那么在throws后面要全部列举出那些没有被方法自身捕获的所有异常类,中间以逗号分隔。</p>
<p align="left"><a href="index.htm">回目录</a> <a href="java06_04.htm">上一课</a>
<a href="java06_06.htm">下一课</a></p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -