﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-村東頭-随笔分类-Java EE</title><link>http://www.blogjava.net/imdosop/category/35072.html</link><description>还记得年少时的梦吗</description><language>zh-cn</language><lastBuildDate>Fri, 13 Jan 2012 20:26:26 GMT</lastBuildDate><pubDate>Fri, 13 Jan 2012 20:26:26 GMT</pubDate><ttl>60</ttl><item><title>Java异常处理之陋习</title><link>http://www.blogjava.net/imdosop/archive/2008/10/10/233545.html</link><dc:creator>東頭bing阿頭</dc:creator><author>東頭bing阿頭</author><pubDate>Fri, 10 Oct 2008 03:54:00 GMT</pubDate><guid>http://www.blogjava.net/imdosop/archive/2008/10/10/233545.html</guid><wfw:comment>http://www.blogjava.net/imdosop/comments/233545.html</wfw:comment><comments>http://www.blogjava.net/imdosop/archive/2008/10/10/233545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/imdosop/comments/commentRss/233545.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/imdosop/services/trackbacks/233545.html</trackback:ping><description><![CDATA[你觉得自己是一个Java专家吗？是否肯定自己已经全面掌握了Java的异常处理机制？在下面这段代码中，你能够迅速找出异常处理的六个问题吗？&nbsp; <br />
<br />
1&nbsp;OutputStreamWriter&nbsp;out&nbsp;=&nbsp;...<br />
2&nbsp;java.sql.Connection&nbsp;conn&nbsp;=&nbsp;...<br />
3&nbsp;try&nbsp;{&nbsp;//&nbsp;⑸<br />
4&nbsp;&nbsp;&nbsp;&nbsp;Statement&nbsp;stat&nbsp;=&nbsp;conn.createStatement();<br />
5&nbsp;&nbsp;&nbsp;&nbsp;ResultSet&nbsp;rs&nbsp;=&nbsp;stat.executeQuery(<br />
6&nbsp;&nbsp;&nbsp;&nbsp;"select&nbsp;uid,&nbsp;name&nbsp;from&nbsp;user");<br />
7&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(rs.next())<br />
8&nbsp;&nbsp;&nbsp;&nbsp;{<br />
9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("ID："&nbsp;+&nbsp;rs.getString("uid")&nbsp;//&nbsp;⑹<br />
10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"，姓名："&nbsp;+&nbsp;rs.getString("name"));<br />
11&nbsp;&nbsp;&nbsp;}<br />
12&nbsp;&nbsp;&nbsp;conn.close();&nbsp;//&nbsp;⑶<br />
13&nbsp;&nbsp;&nbsp;out.close();<br />
14&nbsp;}<br />
15&nbsp;catch(Exception&nbsp;ex)&nbsp;//&nbsp;⑵<br />
16&nbsp;{<br />
17&nbsp;&nbsp;&nbsp;&nbsp;ex.printStackTrace();&nbsp;//⑴，⑷<br />
18&nbsp;}<br />
<br />
　　作为一个Java程序员，你至少应该能够找出两个问题。但是，如果你不能找出全部六个问题，请继续阅读本文。&nbsp; <br />
　　本文讨论的不是Java异常处理的一般性原则，因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为&#8220;反例&#8221;（anti-pattern）的违背优秀编码规范的常见坏习惯，帮助读者熟悉这些典型的反面例子，从而能够在实际工作中敏锐地察觉和避免这些问题。&nbsp;<br />
　　反例之一：丢弃异常 <br />
　　代码：15行-18行。&nbsp; <br />
　　这段代码捕获了异常却不作任何处理，可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看，它也许可以和C/C++程序的一个恶名远播的问题相提并论——不检查缓冲区是否已满。如果你看到了这种丢弃（而不是抛出）异常的情况，可以百分之九十九地肯定代码存在问题（在极少数情况下，这段代码有存在的理由，但最好加上完整的注释，以免引起别人误解）。&nbsp; <br />
　　这段代码的错误在于，异常（几乎）总是意味着某些事情不对劲了，或者说至少发生了某些不寻常的事情，我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上&#8220;处理异常&#8221;。不错，调用printStackTrace对调试程序有帮助，但程序调试阶段结束之后，printStackTrace就不应再在异常处理模块中担负主要责任了。&nbsp; <br />
　　丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档，可以看到下面这段说明：&#8220;特别地，虽然出现ThreadDeath是一种&#8216;正常的情形&#8217;，但ThreadDeath类是Error而不是Exception的子类，因为许多应用会捕获所有的Exception然后丢弃它不再理睬。&#8221;这段话的意思是，虽然ThreadDeath代表的是一种普通的问题，但鉴于许多应用会试图捕获所有异常然后不予以适当的处理，所以JDK把ThreadDeath定义成了Error的子类，因为Error类代表的是一般的应用不应该去捕获的严重问题。可见，丢弃异常这一坏习惯是如此常见，它甚至已经影响到了Java本身的设计。&nbsp; <br />
　　那么，应该怎样改正呢？主要有四个选择：&nbsp; <br />
　　1、处理异常。针对该异常采取一些行动，例如修正问题、提醒某个人或进行其他一些处理，要根据具体的情形确定应该采取的动作。再次说明，调用printStackTrace算不上已经&#8220;处理好了异常&#8221;。&nbsp; <br />
　　2、重新抛出异常。处理异常的代码在分析异常之后，认为自己不能处理它，重新抛出异常也不失为一种选择。<br />
　　3、把该异常转换成另一种异常。大多数情况下，这是指把一个低级的异常转换成应用级的异常（其含义更容易被用户了解的异常）。&nbsp; <br />
　　4、不要捕获异常。&nbsp; <br />
<br />
　　结论一：既然捕获了异常，就要对它进行适当的处理。不要捕获异常之后又把它丢弃，不予理睬。&nbsp; <br />
<br />
<br />
　　反例之二：不指定具体的异常&nbsp; <br />
　　代码：15行。&nbsp; <br />
　　许多时候人们会被这样一种&#8220;美妙的&#8221;想法吸引：用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception&nbsp;ex)语句。但实际上，在绝大多数情况下，这种做法不值得提倡。为什么呢？&nbsp; <br />
　　要理解其原因，我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常，而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生，catch(Exception&nbsp;ex)就相当于说我们想要处理几乎所有的异常。&nbsp; <br />
　　再来看看前面的代码例子。我们真正想要捕获的异常是什么呢？最明显的一个是SQLException，这是JDBC操作中常见的异常。另一个可能的异常是IOException，因为它要操作OutputStreamWriter。显然，在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说，catch语句应当尽量指定具体的异常类型，而不应该指定涵盖范围太广的Exception类。&nbsp; <br />
　　另一方面，除了这两个特定的异常，还有其他许多异常也可能出现。例如，如果由于某种原因，executeQuery返回了null，该怎么办？答案是让它们继续抛出，即不必捕获也不必处理。实际上，我们不能也不应该去捕获可能出现的所有异常，程序的其他地方还有捕获异常的机会——直至最后由JVM处理。&nbsp; <br />
　　结论二：在catch语句中尽可能指定具体的异常类型，必要时使用多个catch。不要试图处理所有可能出现的异常。&nbsp; <br />
<br />
　　反例之三：占用资源不释放&nbsp; <br />
<br />
　　代码：3行-14行。&nbsp; <br />
　　异常改变了程序正常的执行流程。这个道理虽然简单，却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源，即使遇到了异常，也要正确释放占用的资源。为此，Java提供了一个简化这类操作的关键词finally。&nbsp; <br />
　　finally是样好东西：不管是否出现了异常，Finally保证在try/catch/finally块结束之前，执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。&nbsp; <br />
　　当然，编写finally块应当多加小心，特别是要注意在finally块之内抛出的异常——这是执行清理任务的最后机会，尽量不要再有难以处理的错误。&nbsp; <br />
<br />
　　结论三：保证所有资源都被正确释放。充分运用finally关键词。&nbsp; <br />
<br />
　　反例之四：不说明异常的详细信息&nbsp; <br />
<br />
　　代码：3行-18行。&nbsp; <br />
<br />
　　仔细观察这段代码：如果循环内部出现了异常，会发生什么事情？我们可以得到足够的信息判断循环内部出错的原因吗？不能。我们只能知道当前正在处理的类发生了某种错误，但却不能获得任何信息判断导致当前错误的原因。&nbsp; <br />
　　printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程，但只提供了一些最基本的信息，未能说明实际导致错误的原因，同时也不易解读。&nbsp; <br />
&nbsp;&nbsp;&nbsp; 　因此，在出现异常时，最好能够提供一些文字信息，例如当前正在执行的类、方法和其他状态信息，包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。&nbsp; <br />
<br />
　　结论四：在异常处理模块中提供适量的错误原因信息，组织错误信息使其易于理解和阅读。&nbsp; <br />
<br />
　　反例之五：过于庞大的try块&nbsp; <br />
<br />
　　代码：3行-14行。&nbsp; <br />
<br />
　　经常可以看到有人把大量的代码放入单个try块，实际上这不是好习惯。这种现象之所以常见，原因就在于有些人图省事，不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子，虽然东西是带上了，但要找出来可不容易。&nbsp; <br />
　　一些新手常常把大量的代码放入单个try块，然后再在catch语句中声明Exception，而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难，因为一大段代码中有太多的地方可能抛出Exception。&nbsp; <br />
<br />
　　结论五：尽量减小try块的体积。&nbsp; <br />
<br />
　　反例之六：输出数据不完整&nbsp; <br />
<br />
　　代码：7行-11行。&nbsp; <br />
<br />
　　不完整的数据是Java程序的隐形杀手。仔细观察这段代码，考虑一下如果循环的中间抛出了异常，会发生什么事情。循环的执行当然是要被打断的，其次，catch块会执行——就这些，再也没有其他动作了。已经输出的数据怎么办？使用这些数据的人或设备将收到一份不完整的（因而也是错误的）数据，却得不到任何有关这份数据是否完整的提示。对于有些系统来说，数据不完整可能比系统停止运行带来更大的损失。&nbsp; <br />
　　较为理想的处置办法是向输出设备写一些信息，声明数据的不完整性；另一种可能有效的办法是，先缓冲要输出的数据，准备好全部数据之后再一次性输出。&nbsp; <br />
<br />
　　结论六：全面考虑可能出现的异常以及这些异常对执行流程的影响。&nbsp; <br />
<br />
<br />
　　改写后的代码&nbsp; <br />
　　根据上面的讨论，下面给出改写后的代码。也许有人会说它稍微有点啰嗦，但是它有了比较完备的异常处理机制。&nbsp; <br />
<pre>
OutputStreamWriter&nbsp;out&nbsp;=&nbsp;...
java.sql.Connection&nbsp;conn&nbsp;=&nbsp;...
try&nbsp;{
&nbsp;&nbsp;&nbsp;Statement&nbsp;stat&nbsp;=&nbsp;conn.createStatement();
&nbsp;&nbsp;&nbsp;ResultSet&nbsp;rs&nbsp;=&nbsp;stat.executeQuery(
&nbsp;&nbsp;&nbsp;"select&nbsp;uid,&nbsp;name&nbsp;from&nbsp;user");
&nbsp;&nbsp;&nbsp;while&nbsp;(rs.next())
&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("ID："&nbsp;+&nbsp;rs.getString("uid")&nbsp;+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"，姓名:&nbsp;"&nbsp;+&nbsp;rs.getString("name"));
&nbsp;&nbsp;&nbsp;}
}
catch(SQLException&nbsp;sqlex)
{
&nbsp;&nbsp;&nbsp;out.println("警告：数据不完整");
&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ApplicationException(
&nbsp;&nbsp;&nbsp;"读取数据时出现SQL错误",&nbsp;sqlex);
}
catch(IOException&nbsp;ioex)
{
&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ApplicationException(
&nbsp;&nbsp;&nbsp;"写入数据时出现IO错误",&nbsp;ioex);
<br />
}
finally
{
&nbsp;&nbsp;&nbsp;if&nbsp;(conn&nbsp;!=&nbsp;null)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch(SQLException&nbsp;sqlex2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err(this.getClass().getName()&nbsp;+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".mymethod&nbsp;-&nbsp;不能关闭数据库连接:&nbsp;"&nbsp;+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sqlex2.toString());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;}
<br />
&nbsp;&nbsp;&nbsp;if&nbsp;(out&nbsp;!=&nbsp;null)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.close();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch(IOException&nbsp;ioex2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err(this.getClass().getName()&nbsp;+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".mymethod&nbsp;-&nbsp;不能关闭输出文件"&nbsp;+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ioex2.toString());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;}
}
<br />
本文的结论不是放之四海皆准的教条，有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心，务必加上详细、全面的注释。 <br />
另一方面，不要笑话这些错误，不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途，原因很简单，因为它们确确实实带来了&#8220;方便&#8221;。所有这些反例都可以看作Java编程世界的恶魔，它们美丽动人，无孔不入，时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事，不足挂齿，但请记住：勿以恶小而为之，勿以善小而不为。</pre>
<p><em style="font-size: 10pt; color: #c0c0c0">版权归原作者和各发布网站所有，此文章仅供学习参考之用</em></p>
 <img src ="http://www.blogjava.net/imdosop/aggbug/233545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/imdosop/" target="_blank">東頭bing阿頭</a> 2008-10-10 11:54 <a href="http://www.blogjava.net/imdosop/archive/2008/10/10/233545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java异常处理机制的深入理解&lt;一&gt;</title><link>http://www.blogjava.net/imdosop/archive/2008/10/10/233526.html</link><dc:creator>東頭bing阿頭</dc:creator><author>東頭bing阿頭</author><pubDate>Fri, 10 Oct 2008 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/imdosop/archive/2008/10/10/233526.html</guid><wfw:comment>http://www.blogjava.net/imdosop/comments/233526.html</wfw:comment><comments>http://www.blogjava.net/imdosop/archive/2008/10/10/233526.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/imdosop/comments/commentRss/233526.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/imdosop/services/trackbacks/233526.html</trackback:ping><description><![CDATA[1 引子<br />
<span>try&#8230;catch&#8230;finally恐怕是大家再熟悉不过的语句了，而且感觉用起来也是很简单，逻辑上似乎也是很容易理解。不过，我亲自体验的&#8220;教训&#8221;告诉我，这个东西可不是想象中的那么简单、听话。不信？那你看看下面的代码<span>，&#8220;猜猜&#8221;它执行后的结果会是什么？不要往后看答案、也不许执行代码看真正答案哦。如果你的答案是正确，那么这篇文章你就不用浪费时间看啦。</span></span><br />
package myExample.testException;<br />
public class TestException {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public TestException() {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;boolean testEx() throws Exception{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean ret = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = testEx1();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch (Exception e){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx, catch exception");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = false;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw e;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}finally{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx, finally; return value="+ret);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;boolean testEx1() throws Exception{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean ret = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = testEx2();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!ret){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
System.out.println("testEx1, at the end of try");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch (Exception e){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx1, catch exception");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = false;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw e;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx1, finally; return value="+ret);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;boolean testEx2() throws Exception{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean ret = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int b=12;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int c;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i=2;i&gt;=-2;i--){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c=b/i;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("i="+i);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch (Exception e){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx2, catch exception");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = false;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw e;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx2, finally; return value="+ret);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestException testException1 = new TestException();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;testException1.testEx();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(Exception e){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
<br />
<br />
<br />
<br />
<br />
你的答案是什么？是下面的答案吗？<br />
<br />
i=2<br />
<br />
i=1<br />
<br />
testEx2, catch exception<br />
<br />
testEx2, finally; return value=false<br />
<br />
testEx1, catch exception<br />
<br />
testEx1, finally; return value=false<br />
<br />
testEx, catch exception<br />
<br />
testEx, finally; return value=false<br />
<br />
<br />
<span>如果你的答案真的如上面所说，那么你错啦。^_^，那就建议你仔细看一看这篇文章或者拿上面的代码按各种不同的情况修改、执行、测试，你会发现有很多事情不是原来想象中的那么简单的。</span><br />
<br />
现在公布正确答案：<br />
<br />
i=2<br />
<br />
i=1<br />
<br />
testEx2, catch exception<br />
<br />
testEx2, finally; return value=false<br />
<br />
testEx1, finally; return value=false<br />
<br />
testEx, finally; return value=false<br />
<br />
<br />
<br />
2 基础知识<br />
2.1&nbsp; 相关概念<br />
<span>例外是在程序运行过程中发生的异常事件，比如除0溢出、数组越界、文件找不到等，这些事件的发生将阻止程序的正常运行。为了加强程序的鲁棒性，程序设计时，必须考虑到可能发生的异常事件并做出相应的处理。C语言中，通过使用if语句来判断是否出现了例外，同时，调用函数通过被调用函数的返回值<a id="vad_7" onmouseover="this.style.borderBottom='2px #FF3366 solid';var fxEvent=arguments[0];kwmouseover(this,7,fxEvent);" style="font-size: 1em; cursor: pointer; color: #ff3366; border-bottom: #ff3366 1px dotted; text-decoration: underline" onmouseout="this.style.borderBottom='1px #FF3366 dotted'; kwmouseout(this,7)" href="http://action.vogate.com/c/c.php?r=http%3A//www.google.cn/search%3Fcomplete%3D1%26hl%3Dzh-CN%26newwindow%3D1%26q%3Djava%25E5%25BC%2582%25E5%25B8%25B8%25E5%25A4%2584%25E7%2590%2586%26meta%3D%26aq%3Df%26oq%3D&amp;aid=5438&amp;sid=6235007045041189&amp;click=1&amp;url=http%3A//www.5719.cn&amp;v=0&amp;s=http%3A//www.programfan.com/article/2731.html&amp;rn=70071&amp;k=%u611F%u77E5" target="_blank" name="7">感知</a>在被调用函数中产生的例外事件并进行处理。全程变量ErroNo常常用来反映一个异常事件的类型。但是，这种错误处理机制会导致不少问题。</span><br />
<br />
<span>Java通过面向对象的<a id="vad_0" onmouseover="this.style.borderBottom='2px #FF3366 solid';var fxEvent=arguments[0];kwmouseover(this,0,fxEvent);" style="font-size: 1em; cursor: pointer; color: #ff3366; border-bottom: #ff3366 1px dotted; text-decoration: underline" onmouseout="this.style.borderBottom='1px #FF3366 dotted'; kwmouseout(this,0)" href="http://action.vogate.com/c/c.php?r=http%3A//www.google.cn/search%3Fcomplete%3D1%26hl%3Dzh-CN%26newwindow%3D1%26q%3Djava%25E5%25BC%2582%25E5%25B8%25B8%25E5%25A4%2584%25E7%2590%2586%26meta%3D%26aq%3Df%26oq%3D&amp;aid=6691&amp;sid=6235007045041189&amp;click=1&amp;url=http%3A//www.311.cn&amp;v=0&amp;s=http%3A//www.programfan.com/article/2731.html&amp;rn=531190&amp;k=%u65B9%u6CD5" target="_blank" name="0">方法</a><span><span>来处理例外。在一个方法的运行过程中，如果发生了例外，则这个方法生成代表该例外的一个对象，并把它交给运行时系统，运行时系统寻找相应的代码来处理这一例外。我们把生成例外对象并把它提交给运行时系统的过程称为抛弃(throw)一个例外。运行时系统在方法的调用栈中查找，从生成例外的方法</span><a id="vad_4" onmouseover="this.style.borderBottom='2px #FF3366 solid';var fxEvent=arguments[0];kwmouseover(this,4,fxEvent);" style="font-size: 1em; cursor: pointer; color: #ff3366; border-bottom: #ff3366 1px dotted; text-decoration: underline" onmouseout="this.style.borderBottom='1px #FF3366 dotted'; kwmouseout(this,4)" href="http://action.vogate.com/c/c.php?r=http%3A//www.google.cn/search%3Fcomplete%3D1%26hl%3Dzh-CN%26newwindow%3D1%26q%3Djava%25E5%25BC%2582%25E5%25B8%25B8%25E5%25A4%2584%25E7%2590%2586%26meta%3D%26aq%3Df%26oq%3D&amp;aid=10150&amp;sid=6235007045041189&amp;click=1&amp;url=http%3A//www.vogate.com/bbs&amp;v=0&amp;s=http%3A//www.programfan.com/article/2731.html&amp;rn=374379&amp;k=%u5F00%u59CB" target="_blank" name="4">开始</a>进行回朔，直到找到包含相应例外处理的方法为止，这一个过程称为捕获(catch)一个例外。</span></span><br />
<br />
2.2&nbsp; Throwable类及其子类<br />
<span><span>　用面向对象的方法处理例外，就必须建立类的层次。类 Throwable位于这一类层次的最顶层，只有它的后代才<a id="vad_3" onmouseover="this.style.borderBottom='2px #FF3366 solid';var fxEvent=arguments[0];kwmouseover(this,3,fxEvent);" style="font-size: 1em; cursor: pointer; color: #ff3366; border-bottom: #ff3366 1px dotted; text-decoration: underline" onmouseout="this.style.borderBottom='1px #FF3366 dotted'; kwmouseout(this,3)" href="http://action.vogate.com/c/c.php?r=http%3A//www.google.cn/search%3Fcomplete%3D1%26hl%3Dzh-CN%26newwindow%3D1%26q%3Djava%25E5%25BC%2582%25E5%25B8%25B8%25E5%25A4%2584%25E7%2590%2586%26meta%3D%26aq%3Df%26oq%3D&amp;aid=10539&amp;sid=6235007045041189&amp;click=1&amp;url=http%3A//tui.01lm.com/counter.aspx%3Fuser%3D99cu666&amp;v=0&amp;s=http%3A//www.programfan.com/article/2731.html&amp;rn=958839&amp;k=%u53EF%u4EE5" target="_blank" name="3">可以</a>做为一个例外被抛弃。图1表示了例外处理的类层次。</span></span><br />
<br />
<span>从图中可以看出，类Throwable有两个直接子类：Error和Exception。Error类对象（如动态连接错误等），由Java虚拟机生成并抛弃（通常，Java程序不对这类例外进行处理）；Exception类对象是Java程序处理或抛弃的对象。它有各种不同的子类分别对应于不同类型的例外。其中类RuntimeException代表运行时由Java虚拟机生成的例外，如算术运算例外ArithmeticException(由除0错等导致)、数组越界例外ArrayIndexOutOfBoundsException等；其它则为非运行时例外，如输入输出例外IOException等。Java编译器要求Java程序必须捕获或声明所有的非运行时例外，但对运行时例外可以不做处理。</span><br />
<br />
2.3&nbsp; 异常处理关键字<br />
Java的异常处理是通过5个关键字来实现的：try，catch，throw，throws，finally。JB的在线帮助中对这几个关键字是这样解释的：<br />
<br />
Throws:&nbsp;&nbsp;Lists the exceptions a method could throw.<br />
<br />
Throw:&nbsp;&nbsp;&nbsp;Transfers control of the method to the exception handler.<br />
<br />
Try：&nbsp;&nbsp;&nbsp;&nbsp;Opening exception-handling statement.<br />
<br />
Catch：&nbsp;&nbsp;Captures the exception.<br />
<br />
Finally： Runs its code before terminating the program.<br />
<br />
2.3.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try语句　<br />
<span>try语句用大括号{}指定了一段代码，该段代码可能会抛弃一个或多个例外。</span><br />
<br />
2.3.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch语句　<br />
<span><span><span>catch语句的参数类似于方法的声明，包括一个例外类型和一个例外对象。例外类型必须为Throwable类的子类，它指明了catch语句所处理的例外类型，例外对象则由运行时系统在try所指定的代码块中生成并被捕获，大括号中包含对象的处理，其中可以调用对象的方法。</span></span></span><br />
<br />
<span>catch语句可以有多个，分别处理不同类的例外。Java运行时系统从上到下分别对每个catch语句处理的例外类型进行检测，直到找到类型相匹配的catch语句为止。这里，类型匹配指catch所处理的例外类型与生成的例外对象的类型完全一致或者是它的父类，因此，catch语句的排列顺序应该是从特殊到一般。</span><br />
<br />
<br />
<br />
<span>也可以用一个catch语句处理多个例外类型，这时它的例外类型参数应该是这多个例外类型的父类，程序设计中要根据具体的情况来选择catch语句的例外处理类型。　</span><br />
<br />
2.3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally语句　<br />
<span><span>try所限定的代码中，当抛弃一个例外时，其后的代码不会被执行。通过finally语句可以指定一块代码。无论try所指定的程序块中抛弃或不抛弃例外，也无论catch语句的例外类型是否与所抛弃的例外的类型一致，finally所指定的代码都要被执行，它提供了统一的出口。通常在finally语句中可以进行资源的清除工作。如关闭打开的文件等。</span></span><br />
<br />
2.3.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws语句　<br />
throws总是出现在一个函数头中，用来标明该成员函数可能抛出的各种异常。对大多数Exception子类来说，Java 编译器会强迫你声明在一个成员函数中抛出的异常的类型。如果异常的类型是Error或 RuntimeException， 或它们的子类，这个规则不起作用， 因为这在程序的正常部分中是不期待出现的。 如果你想明确地抛出一个RuntimeException，你必须用throws语句来声明它的类型。<br />
<br />
2.3.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw语句　<br />
throw总是出现在函数体中，用来抛出一个异常。程序会在throw语句后立即终止，它后面的语句执行不到，然后在包含它的所有try块中（可能在上层调用函数中）从里向外寻找含有与其匹配的catch子句的try块。<br />
<br />
<br />
<br />
<br />
<br />
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关键字及其中语句流程详解<br />
3.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try的嵌套<br />
<span><span>你可以在一个成员函数调用的外面写一个try语句，在这个成员函数内部，写另一个try语句保护其他代码。每当遇到一个try语句，异常的框架就放到堆栈上面，直到所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理，堆栈就会展开，直到遇到有处理这种异常的try语句。下面是一个try语句嵌套的例子。 </span></span><br />
<br />
class MultiNest {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;static void procedure() {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int a = 0;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int b = 42/a;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch(java.lang.ArithmeticException e) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("in procedure, catch ArithmeticException: " + e);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String args[]) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;procedure();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch(java.lang. Exception e) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("in main, catch Exception: " + e);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
<br />
<br />
<br />
<br />
<br />
这个例子执行的结果为：<br />
<br />
in procedure, catch ArithmeticException: java.lang.ArithmeticException: / by zero<br />
<br />
<br />
<br />
<span>成员函数procedure里有自己的try/catch控制，所以main不用去处理 ArrayIndexOutOfBoundsException；当然如果如同最开始我们做测试的例子一样，在procedure中catch到异常时使用throw e;语句将异常抛出，那么main当然还是能够捕捉并处理这个procedure抛出来的异常。例如在procedure函数的catch中的System.out语句后面增加throw e;语句之后，执行结果就变为：</span><br />
<br />
in procedure, catch ArithmeticException: java.lang.ArithmeticException: / by zero<br />
<br />
<br />
<br />
in main, catch Exception: java.lang.ArithmeticException: / by zero<br />
<br />
<br />
<br />
<br />
3.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try-catch程序块的执行流程以及执行结果<br />
相对于try-catch-finally程序块而言，try-catch的执行流程以及执行结果还是比较简单的。<br />
<br />
首先执行的是try语句块中的语句，这时可能会有以下三种情况：<br />
<br />
1．&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果try块中所有语句正常执行完毕，那么就不会有其他的&#8220;动做&#8221;被执行，整个try-catch程序块正常完成。<br />
<br />
2．&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果try语句块在执行过程中碰到异常V，这时又分为两种情况进行处理：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果异常V能够被与try相应的catch块catch到，那么第一个catch到这个异常的catch块（也是离try最近的一个与异常V匹配的catch块）将被执行；如果catch块执行正常，那么try-catch程序块的结果就是&#8220;正常完成&#8221;；如果该catch块由于原因R突然中止，那么try-catch程序块的结果就是&#8220;由于原因R突然中止（completes abruptly）&#8221;。<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果异常V没有catch块与之匹配，那么这个try-catch程序块的结果就是&#8220;由于抛出异常V而突然中止（completes abruptly）&#8221;。<br />
<br />
3．&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果try由于其他原因R突然中止（completes abruptly），那么这个try-catch程序块的结果就是&#8220;由于原因R突然中止（completes abruptly）&#8221;。<br />
<br />
3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try-catch-finally程序块的执行流程以及执行结果<br />
try-catch-finally程序块的执行流程以及执行结果比较复杂。<br />
<br />
首先执行的是try语句块中的语句，这时可能会有以下三种情况：<br />
<br />
1．&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果try块中所有语句正常执行完毕，那么finally块的居于就会被执行，这时分为以下两种情况：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块执行顺利，那么整个try-catch-finally程序块正常完成。<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块由于原因R突然中止，那么try-catch-finally程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;<br />
<br />
2．&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果try语句块在执行过程中碰到异常V，这时又分为两种情况进行处理：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果异常V能够被与try相应的catch块catch到，那么第一个catch到这个异常的catch块（也是离try最近的一个与异常V匹配的catch块）将被执行；这时就会有两种执行结果：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果catch块执行正常，那么finally块将会被执行，这时分为两种情况：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块执行顺利，那么整个try-catch-finally程序块正常完成。<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块由于原因R突然中止，那么try-catch-finally程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果catch块由于原因R突然中止，那么finally模块将被执行，分为两种情况：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果如果finally块执行顺利，那么整个try-catch-finally程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;。<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块由于原因S突然中止，那么整个try-catch-finally程序块的结局是&#8220;由于原因S突然中止（completes abruptly）&#8221;，原因R将被抛弃。<br />
<br />
（注意，这里就正好和我们的例子相符合，虽然我们在testEx2中使用throw e抛出了异常，但是由于testEx2中有finally块，而finally块的执行结果是complete abruptly的（别小看这个用得最多的return，它也是一种导致complete abruptly的原因之一啊——后文中有关于导致complete abruptly的原因分析），所以整个try-catch-finally程序块的结果是&#8220;complete abruptly&#8221;，所以在testEx1中调用testEx2时是捕捉不到testEx1中抛出的那个异常的，而只能将finally中的return结果获取到。<br />
<br />
<span><span>如果在你的代码中期望通过捕捉被调用的下级函数的异常来给定返回值，那么一定要注意你所调用的下级函数中的finally语句，它有可能会使你throw出来的异常并不能真正被上级调用函数可见的。当然这种情况是可以避免的，以testEx2为例：如果你一定要使用finally而且又要将catch中throw的e在testEx1中被捕获到，那么你去掉testEx2中的finally中的return就可以了。</span></span><br />
<br />
<br />
<br />
这个事情已经在OMC2.0的MIB中出现过啦：服务器的异常不能完全被反馈到客户端。）<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果异常V没有catch块与之匹配，那么finally模块将被执行，分为两种情况：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块执行顺利，那么整个try-catch-finally程序块的结局就是&#8220;由于抛出异常V而突然中止（completes abruptly）&#8221;。<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块由于原因S突然中止，那么整个try-catch-finally程序块的结局是&#8220;由于原因S突然中止（completes abruptly）&#8221;，异常V将被抛弃。<br />
<br />
3．&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果try由于其他原因R突然中止（completes abruptly），那么finally块被执行，分为两种情况：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块执行顺利，那么整个try-catch-finally程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;。<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果finally块由于原因S突然中止，那么整个try-catch-finally程序块的结局是&#8220;由于原因S突然中止（completes abruptly）&#8221;，原因R将被抛弃。<br />
<br />
3.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try-catch-finally程序块中的return<br />
<span>从上面的try-catch-finally程序块的执行流程以及执行结果一节中可以看出无论try或catch中发生了什么情况，finally都是会被执行的，那么写在try或者catch中的return语句也就不会真正的从该函数中跳出了，它的作用在这种情况下就变成了将控制权（语句流程）转到finally块中；这种情况下一定要注意返回值的处理。</span><br />
<br />
例如，在try或者catch中return false了，而在finally中又return true，那么这种情况下不要期待你的try或者catch中的return false的返回值false被上级调用函数获取到，上级调用函数能够获取到的只是finally中的返回值，因为try或者catch中的return语句只是转移控制权的作用。<br />
<br />
3.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如何抛出异常<br />
如果你知道你写的某个函数有可能抛出异常，而你又不想在这个函数中对异常进行处理，只是想把它抛出去让调用这个函数的上级调用函数进行处理，那么有两种方式可供选择：<br />
<br />
<span>第一种方式：直接在函数头中throws SomeException，函数体中不需要try/catch。比如将最开始的例子中的testEx2改为下面的方式，那么testEx1就能捕捉到testEx2抛出的异常了。</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;boolean testEx2() throws Exception{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean ret = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int b=12;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int c;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i=2;i&gt;=-2;i--){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c=b/i;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("i="+i);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
}<br />
<br />
<br />
<br />
<br />
<br />
第二种方式：使用try/catch，在catch中进行一定的处理之后（如果有必要的话）抛出某种异常。例如上面的testEx2改为下面的方式，testEx1也能捕获到它抛出的异常：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;boolean testEx2() throws Exception{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean ret = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int b=12;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int c;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i=2;i&gt;=-2;i--){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c=b/i;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("i="+i);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch (Exception e){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx2, catch exception");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throw e;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
<br />
<br />
<br />
<span>第三种方法：使用try/catch/finally，在catch中进行一定的处理之后（如果有必要的话）抛出某种异常。例如上面的testEx2改为下面的方式，testEx1也能捕获到它抛出的异常：</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;boolean testEx2() throws Exception{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean ret = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int b=12;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int c;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i=2;i&gt;=-2;i--){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c=b/i;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("i="+i);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Exception("aaa");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch (java.lang.ArithmeticException e){<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx2, catch exception");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = false;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Exception("aaa");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}finally{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("testEx2, finally; return value="+ret);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关于abrupt completion<br />
前面提到了complete abruptly（暂且理解为&#8220;突然中止&#8221;或者&#8220;异常结束&#8221;吧），它主要包含了两种大的情形：abrupt completion of expressions and statements，下面就分两种情况进行解释。<br />
<br />
4.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Normal and Abrupt Completion of Evaluation<br />
每一个表达式（expression）都有一种使得其包含的计算得以一步步进行的正常模式，如果每一步计算都被执行且没有异常抛出，那么就称这个表达式&#8220;正常结束（complete normally）&#8221;；如果这个表达式的计算抛出了异常，就称为&#8220;异常结束（complete abruptly）&#8221;。异常结束通常有一个相关联的原因（associated reason），通常也就是抛出一个异常V。<br />
<br />
与表达式、操作符相关的运行期异常有：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A class instance creation expression, array creation expression , or string concatenation operatior expression throws an OutOfMemoryError if there is insufficient memory available. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An array creation expression throws a NegativeArraySizeException if the value of any dimension expression is less than zero. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A field access throws a NullPointerException if the value of the object reference&nbsp;&nbsp;expression is null. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A method invocation expression that invokes an instance method throws a NullPointerException if the target reference is null. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An array access throws a NullPointerException if the value of the array reference&nbsp;&nbsp;expression is null. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An array access throws an ArrayIndexOutOfBoundsException if the value of the array index expression is negative or greater than or equal to the length of the array. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A cast throws a ClassCastException if a cast is found to be impermissible at run time. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An integer division or integer remainder operator throws an ArithmeticException if the value of the right-hand operand expression is zero. <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An assignment to an array component of reference type throws an ArrayStoreException when the value to be assigned is not compatible with the component type of the array.<br />
<br />
4.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Normal and Abrupt Completion of Statements <br />
正常情况我们就不多说了，在这里主要是列出了abrupt completion的几种情况：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break, continue, and return 语句将导致控制权的转换，从而使得statements不能正常地、完整地执行。 <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;某些表达式的计算也可能从java虚拟机抛出异常，这些表达式在上一小节中已经总结过了；一个显式的的throw语句也将导致异常的抛出。抛出异常也是导致控制权的转换的原因（或者说是阻止statement正常结束的原因）。 <br />
<br />
<br />
<br />
<br />
<br />
如果上述事件发生了，那么这些statement就有可能使得其正常情况下应该都执行的语句不能完全被执行到，那么这些statement也就是被称为是complete abruptly. <br />
<br />
导致abrupt completion的几种原因：<br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A break with no label <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A break with a given label <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A continue with no label <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A continue with a given label <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A return with no value <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A return with a given value A <br />
<br />
&amp;sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw with a given value, including exceptions thrown by the Java virtual machine<br />
<br />
5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关于我们的编程的一点建议<br />
弄清楚try-catch-finally的执行情况后我们才能正确使用它。<br />
<br />
如果我们使用的是try-catch-finally语句块，而我们又需要保证有异常时能够抛出异常，那么在finally语句中就不要使用return语句了（finally语句块的最重要的作用应该是释放申请的资源），因为finally中的return语句会导致我们的throw e被抛弃，在这个try-catch-finally的外面将只能看到finally中的返回值（除非在finally中抛出异常）。（我们需要记住：不仅throw语句是abrupt completion 的原因，return、break、continue等这些看起来很正常的语句也是导致abrupt completion的原因。） <br />
<br />
<em style="font-size: 10pt; color: #c0c0c0">版权归原作者和各发布网站所有，此文章仅供学习参考之用</em>
<img src ="http://www.blogjava.net/imdosop/aggbug/233526.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/imdosop/" target="_blank">東頭bing阿頭</a> 2008-10-10 10:49 <a href="http://www.blogjava.net/imdosop/archive/2008/10/10/233526.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java异常处理学习笔记</title><link>http://www.blogjava.net/imdosop/archive/2008/10/09/233304.html</link><dc:creator>東頭bing阿頭</dc:creator><author>東頭bing阿頭</author><pubDate>Thu, 09 Oct 2008 03:10:00 GMT</pubDate><guid>http://www.blogjava.net/imdosop/archive/2008/10/09/233304.html</guid><wfw:comment>http://www.blogjava.net/imdosop/comments/233304.html</wfw:comment><comments>http://www.blogjava.net/imdosop/archive/2008/10/09/233304.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/imdosop/comments/commentRss/233304.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/imdosop/services/trackbacks/233304.html</trackback:ping><description><![CDATA[<strong>一、异常的概念和Java异常体系结构<br />
</strong>Java把异常当作对象来处理，并定义一个基类java.lang.Throwable作为所有异常的超类。在Java API中已经定义了许多异常类，这些异常类分为两大类，错误Error和异常Exception。<br />
Thorwable类所有异常和错误的超类，有两个子类Error和Exception，分别表示错误和异常。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常，也称之为不检查异常（Unchecked Exception）和检查异常（Checked Exception）。<br />
Error是程序无法处理的错误，比如OutOfMemoryError、ThreadDeath等。这些异常发生时，Java虚拟机（JVM）一般会选择线程终止。 <br />
Exception是程序本身可以处理的异常，这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。<br />
运行时异常都是RuntimeException类及其子类异常，如NullPointerException、IndexOutOfBoundsException等，这些异常是不检查异常，程序中可以选择捕获处理，也可以不处理。这些异常一般是由程序逻辑错误引起的，程序应该从逻辑角度尽可能避免这类异常的发生。<br />
非运行时异常是RuntimeException以外的异常，类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常，如果不处理，程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常，一般情况下不自定义检查异常。<br />
<br />
<strong>二、异常的捕获和处理<br />
</strong>Java异常的捕获和处理是一个不容易把握的事情，如果处理不当，不但会让程序代码的可读性大大降低，而且导致系统性能低下，甚至引发一些难以发现的错误。<br />
Java异常处理涉及到五个关键字，分别是：try、catch、finally、throw、throws。<br />
<p><strong>try、catch、finally三个语句块应注意的问题<br />
</strong>1&gt;try、catch、finally三个语句块均不能单独使用，三者可以组成 try...catch...finally、try...catch、try...finally三种结构，catch语句可以有一个或多个，finally语句最多一个。<br />
2&gt;try、catch、finally三个代码块中变量的作用域为代码块内部，分别独立而不能相互访问。如果要在三个块中都可以访问，则需要将变量定义到这些块的外面。<br />
3&gt;多个catch块时候，只会匹配其中一个异常类并执行catch块代码，而不会再执行别的catch块，并且匹配catch语句的顺序是由上到下。<br />
<strong>throw、throws关键字<br />
</strong>throw关键字是用于方法体内部，用来抛出一个Throwable类型的异常。如果抛出了检查异常，则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。如果所有方法都层层上抛获取的异常，最终JVM会进行处理，处理也很简单，就是打印异常消息和堆栈信息。如果抛出的是Error或RuntimeException，则该方法的调用者可选择处理该异常。<br />
throws关键字用于方法体外部的方法声明部分，用来声明方法可能会抛出某些异常。仅当抛出了检查异常，该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候，应该继续抛出，而不是囫囵吞枣一般在catch块中打印一下堆栈信息做个勉强处理。<br />
<br />
<font style="color: black" color="#0000ff"><strong>三、&nbsp;异常处理的一般原则<br />
</strong>1<strong>&gt;</strong></font>能处理就早处理，抛出不去还不能处理的就想法消化掉或者转换为RuntimeException处理。因为对于一个应用系统来说，抛出大量异常是有问题的，应该从程序开发角度尽可能的控制异常发生的可能。<br />
2&gt;对于检查异常，如果不能行之有效的处理，还不如转换为RuntimeException抛出。这样也让上层的代码有选择的余地――可处理也可不处理。<br />
3&gt;对于一个应用系统来说，应该有自己的一套异常处理框架，这样当异常发生时，也能得到统一的处理风格，将优雅的异常信息反馈给用户。</p>
  <img src ="http://www.blogjava.net/imdosop/aggbug/233304.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/imdosop/" target="_blank">東頭bing阿頭</a> 2008-10-09 11:10 <a href="http://www.blogjava.net/imdosop/archive/2008/10/09/233304.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>