﻿<?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-cpsing的窝-文章分类-Java基础</title><link>http://www.blogjava.net/cpsing/category/18113.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 03:45:23 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 03:45:23 GMT</pubDate><ttl>60</ttl><item><title>javascript 子窗口 父窗口 传值问题</title><link>http://www.blogjava.net/cpsing/articles/94246.html</link><dc:creator>cpsing</dc:creator><author>cpsing</author><pubDate>Tue, 16 Jan 2007 09:13:00 GMT</pubDate><guid>http://www.blogjava.net/cpsing/articles/94246.html</guid><wfw:comment>http://www.blogjava.net/cpsing/comments/94246.html</wfw:comment><comments>http://www.blogjava.net/cpsing/articles/94246.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cpsing/comments/commentRss/94246.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cpsing/services/trackbacks/94246.html</trackback:ping><description><![CDATA[
		<p _fckxhtmljob="1">1. 刷新父窗口</p>
		<p _fckxhtmljob="1">     a  opener.parent.refresh()</p>
		<p _fckxhtmljob="1">      b   opener.location.relaod()</p>
		<p _fckxhtmljob="1">      c  <font color="#0000cc" _fckxhtmljob="1">window</font><font color="#006600" _fckxhtmljob="1">.</font><font color="#0000cc" _fckxhtmljob="1">opener</font><font color="#006600" _fckxhtmljob="1">.</font><font color="#0000cc" _fckxhtmljob="1">location</font><font color="#006600" _fckxhtmljob="1">.</font><font color="#0000cc" _fckxhtmljob="1">href </font><font color="#006600" _fckxhtmljob="1">= </font><font color="#0000cc" _fckxhtmljob="1">window</font><font color="#006600" _fckxhtmljob="1">.</font><font color="#0000cc" _fckxhtmljob="1">opener</font><font color="#006600" _fckxhtmljob="1">.</font><font color="#0000cc" _fckxhtmljob="1">location</font><font color="#006600" _fckxhtmljob="1">.</font><font color="#0000cc" _fckxhtmljob="1">href</font><font color="#006600" _fckxhtmljob="1">;</font></p>
		<p _fckxhtmljob="1">
				<font color="#006600" _fckxhtmljob="1">      d  <font color="#000000" _fckxhtmljob="1">  Page.RegisterStartupScript("","&lt;script&gt;window.showModalDial('scr,'','scroll:0;status:0;help:0;resizable:0;dialogWidth:530px;dialogHeight:350px');document.forms(0).Button2.click();&lt;/script&gt;";);</font><br _fckxhtmljob="1" /></font>   </p>
		<p _fckxhtmljob="1"> </p>
<img src ="http://www.blogjava.net/cpsing/aggbug/94246.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cpsing/" target="_blank">cpsing</a> 2007-01-16 17:13 <a href="http://www.blogjava.net/cpsing/articles/94246.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>异常处理框架-ZT</title><link>http://www.blogjava.net/cpsing/articles/85778.html</link><dc:creator>cpsing</dc:creator><author>cpsing</author><pubDate>Wed, 06 Dec 2006 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/cpsing/articles/85778.html</guid><wfw:comment>http://www.blogjava.net/cpsing/comments/85778.html</wfw:comment><comments>http://www.blogjava.net/cpsing/articles/85778.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cpsing/comments/commentRss/85778.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cpsing/services/trackbacks/85778.html</trackback:ping><description><![CDATA[
		<div class="title">
				<h2>构建更好的异常处理框架</h2>
				<a href="http://www.matrix.org.cn/resource/article/1/user.shtml?userid=2">chris</a> 发表于 2005-03-13 12:00:00<br />作者:McLaughlin     评论数:78 点击数:949     投票总得分:0 投票总人次:0<br />关键字: </div>
		<!-- end of div title -->
		<div class="summary">
				<div class="left">
				</div>
				<div class="center">
						<h4>摘要:</h4>在 EJB 最佳实践的这篇专栏文章中，Brett McLaughlin 解释了为什么对异常处理投入一点关注就会给我们带来很大的帮助，并向您展示了两种简单技术，它们将帮助您正确地构建更健壮且有用的异常处理框架。 </div>
				<div class="right">
						<div class="help">
								<h4>工具箱</h4>
								<a href="http://www.matrix.org.cn/favorite.shtml?type=article&amp;title=%25E6%259E%2584%25E5%25BB%25BA%25E6%259B%25B4%25E5%25A5%25BD%25E7%259A%2584%25E5%25BC%2582%25E5%25B8%25B8%25E5%25A4%2584%25E7%2590%2586%25E6%25A1%2586%25E6%259E%25B6&amp;url=resource%2Farticle%2F1%2F1249.html">本站收藏</a>
								<br />
								<a onclick="javascript:location.href='http://del.icio.us/post?&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title)" href="http://www.matrix.org.cn/resource/article/1/1249.html#">美味书签</a>
								<br />
								<a href="http://www.matrix.org.cn/resource/article/1/1249.html#avote">投票评分</a>
								<br />
								<a href="http://www.matrix.org.cn/resource/article/1/1249.html#areview">发表评论</a>
								<br />
								<a title="点击后直接粘贴即可" onclick="copyLink();" href="http://www.matrix.org.cn/resource/article/1/1249.html#">复制链接</a>
								<br />
						</div>
				</div>
		</div>
		<!-- end of summary line -->
		<div class="overflow" id="text">企业应用程序在构建时常常对异常处理关注甚少，这会造成对低级异常（如 java.rmi.RemoteException 和 javax.naming.NamingException）的过度依赖。在 EJB 最佳实践的这篇专栏文章中，Brett McLaughlin 解释了为什么对异常处理投入一点关注就会给我们带来很大的帮助，并向您展示了两种简单技术，它们将帮助您正确地构建更健壮且有用的异常处理框架。<br /><br />在本系列先前的技巧文章中，异常处理不属于讨论的核心范围之内。但是，您可能会发现一点，那就是我们一直都回避来自 Web 层的低级异常。我们向客户机提供诸如 ApplicationException 和 InvalidDataException 之类的异常，而没有让 Web 层处理象 java.rmi.RemoteException 或 javax.naming.NamingException 这样的异常。<br /><br />远程和命名异常是系统级异常，而应用程序和非法数据异常是业务级异常，因为它们提交更适用的业务信息。当决定抛出何种类型的异常时，您应该总是首先考虑将要处理所报告异常的层。Web 层通常是由执行业务任务的最终用户驱动的，所以最好用它处理业务级异常。但是，在 EJB 层，您正在执行系统级任务，如使用 JNDI 或数据库。尽管这些任务最终将被合并到业务逻辑中，但是最好用诸如 RemoteException 之类的系统级异常来表示它们。<br /><br />理论上，您可以让所有 Web 层方法预期处理和响应单个应用程序异常，正如我们在先前的一些示例中所做的一样。但这种方法不适用于长时间运行。让您的委派方法抛出更具体的异常，这是一个好得多的异常处理方案，从根本上讲，这对接收客户机更有用。在这篇技巧文章中，我们将讨论两种技术，它们将有助于您创建信息更丰富、更具体的异常，而不会生成大量不必要的代码。<br /><br /><b>嵌套的异常</b><br />在设计可靠的异常处理方案时，要考虑的第一件事情就是对所谓的低级或系统级异常进行抽象化。这些核心 Java 异常通常会报告网络流量中的错误、JNDI 或 RMI 问题，或者是应用程序中的其它技术问题。RemoteException、EJBException 和 NamingException 是企业 Java 编程中低级异常的常见例子。<br /><br />这些异常完全没有任何意义，由 Web 层的客户机接收时尤其容易混淆。如果客户机调用 purchase() 并接收到 NamingException，那么它在解决这个异常时会一筹莫展。同时，应用程序代码可能需要访问这些异常中的信息，因此不能轻易地抛弃或忽略它们。<br /><br />答案是提供一类更有用的异常，它还包含低级异常。清单 1 演示了一个专为这一点设计的简单 ApplicationException：<br /><br />清单 1. 嵌套的异常 package com.ibm;<br /><pre class="overflow">import java.io.PrintStream;<br />import java.io.PrintWriter;<br />public class ApplicationException extends Exception {<br />       /** A wrapped Throwable */<br />       protected Throwable cause;<br />       public ApplicationException() {<br />           super("Error occurred in application.");<br />       }<br />       public ApplicationException(String message)  {<br />           super(message);<br />       }<br />       public ApplicationException(String message, Throwable cause)  {<br />           super(message);<br />           this.cause = cause;<br />       }<br />       // Created to match the JDK 1.4 Throwable method.<br />       public Throwable initCause(Throwable cause)  {<br />           this.cause = cause;<br />           return cause;<br />       }<br />       public String getMessage() {<br />           // Get this exception's message.<br />           String msg = super.getMessage();<br />           Throwable parent = this;<br />           Throwable child;<br />           // Look for nested exceptions.<br />           while((child = getNestedException(parent)) != null) {<br />               // Get the child's message.<br />               String msg2 = child.getMessage();<br />               // If we found a message for the child exception, <br />               // we append it.<br />               if (msg2 != null) {<br />                   if (msg != null) {<br />                       msg += ": " + msg2;<br />                   } else {<br />                       msg = msg2;<br />                   }<br />               }<br />               // Any nested ApplicationException will append its own<br />               // children, so we need to break out of here.<br />               if (child instanceof ApplicationException) {<br />                   break;<br />               }<br />               parent = child;<br />           }<br />           // Return the completed message.<br />           return msg;<br />       }<br />       public void printStackTrace() {<br />           // Print the stack trace for this exception.<br />           super.printStackTrace();<br />           Throwable parent = this;<br />           Throwable child;<br />           // Print the stack trace for each nested exception.<br />           while((child = getNestedException(parent)) != null) {<br />               if (child != null) {<br />                   System.err.print("Caused by: ");<br />                   child.printStackTrace();<br />                   if (child instanceof ApplicationException) {<br />                       break;<br />                   }<br />                   parent = child;<br />               }<br />           }<br />       }<br />       public void printStackTrace(PrintStream s) {<br />           // Print the stack trace for this exception.<br />           super.printStackTrace(s);<br />           Throwable parent = this;<br />           Throwable child;<br />           // Print the stack trace for each nested exception.<br />           while((child = getNestedException(parent)) != null) {<br />               if (child != null) {<br />                   s.print("Caused by: ");<br />                   child.printStackTrace(s);<br />                   if (child instanceof ApplicationException) {<br />                       break;<br />                   }<br />                   parent = child;<br />               }<br />           }<br />       }<br />       public void printStackTrace(PrintWriter w) {<br />           // Print the stack trace for this exception.<br />           super.printStackTrace(w);<br />           Throwable parent = this;<br />           Throwable child;<br />           // Print the stack trace for each nested exception.<br />           while((child = getNestedException(parent)) != null) {<br />               if (child != null) {<br />                   w.print("Caused by: ");<br />                   child.printStackTrace(w);<br />                   if (child instanceof ApplicationException) {<br />                       break;<br />                   }<br />                   parent = child;<br />               }<br />           }<br />       }<br />       public Throwable getCause()  {<br />           return cause;<br />       }<br />}</pre><br /><br /><br /><br /><br /><br />清单 1 中的代码很简单；我们已经简单地将多个异常“串”在一起，以创建单个、嵌套的异常。但是，真正的好处在于将这种技术作为出发点，以创建特定于应用程序的异常层次结构。异常层次结构将允许 EJB 客户机既接收特定于业务的异常也接收特定于系统的信息，而不需要编写大量额外代码。<br /><br /><b>异常层次结构</b><br />异常层次结构应该从一些十分健壮而又通用的异常入手，如 ApplicationException。如果您将顶级异常搞得太具体，那么其结果是您今后将不得不重新构造层次结构，以适应某些较通用的情况。<br /><br />因此，让我们假定您的应用程序要求 NoSuchBookException、InsufficientFundsException 和 SystemUnavailableException。您不必创建这三个异常，让它们继承 ApplicationException，然后只需提供极少几个必须的构造器来创建格式化的消息。清单 2 是此类异常层次结构的示例：<br /><br />清单 2. 异常层次结构 package com.ibm.library;<br /><pre class="overflow">import com.ibm.ApplicationException;<br />public class NoSuchBookException extends ApplicationException {<br />       public NoSuchBookException(String bookName, String libraryName) {<br />        super("The book '" + bookName + "' was not found in the '" +<br />            libraryName + "' library.");<br />    }<br />}</pre><br /><br /><br /><br /><br />当需要编写大量专用异常时，异常层次结构极大地简化了工作。对于一个异常，为每个异常类添加一个或两个构造器，所花费时间很少不超过几分钟。您还经常需要给这些更具体的异常（这些异常也是主应用程序异常的子类）提供子类，以提供更具体的异常。例如，您可能需要 InvalidTitleException 和 BackorderedException 来继承 NoSuchBookException。<br /><br />企业应用程序在构建时通常都不会注意异常处理。尽管依靠低级异常（如 RemoteException 和 NamingException）很容易（有时也很诱人），但如果一开始就建立一个可靠的、深思熟虑的异常模型，则您将在应用程序上少花很多精力。创建一个嵌套的、层次结构化的异常框架将改进代码的可读性及其可用性。<br /><br /><br />关于作者<br />Brett McLaughlin 从 Logo 时代（还记得那个小三角吗？）就开始从事计算机工作了。他现在专门研究用 Java 和 Java 相关技术构建应用程序基础结构。过去几年他一直在 Nextel Communications 和 Allegiance Telecom, Inc. 致力于实现这些基础结构。Brett 是 Java Apache 项目 Turbine 的共同创始人之一，该项目为使用 Java servlet 的 Web 应用程序开发构建可重用的组件体系结构。他还是 EJBoss 项目（一个开放源码 EJB 应用程序服务器）和 Cocoon（一个开放源码 XML Web 发布引擎）的志愿开发人员之一。可通过 brett@oreilly.com 与 Brett 联系。 <br /></div>
<img src ="http://www.blogjava.net/cpsing/aggbug/85778.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cpsing/" target="_blank">cpsing</a> 2006-12-06 11:03 <a href="http://www.blogjava.net/cpsing/articles/85778.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java异常处理技术-ZT</title><link>http://www.blogjava.net/cpsing/articles/85777.html</link><dc:creator>cpsing</dc:creator><author>cpsing</author><pubDate>Wed, 06 Dec 2006 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/cpsing/articles/85777.html</guid><wfw:comment>http://www.blogjava.net/cpsing/comments/85777.html</wfw:comment><comments>http://www.blogjava.net/cpsing/articles/85777.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cpsing/comments/commentRss/85777.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cpsing/services/trackbacks/85777.html</trackback:ping><description><![CDATA[
		<span id="ArticleContent1_ArticleContent1_lblContent">  
<p><font size="2">六种异常处理的陋习</font></p><p><font size="2">你觉得自己是一个Java专家吗？是否肯定自己已经全面掌握了Java的异常处理机制？在下面这段代码中，你能够迅速找出异常处理的六个问题吗？ <br /><br /></font></p><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td><font size="2">1 OutputStreamWriter out = ... <br />2 java.sql.Connection conn = ... <br />3 try { // ⑸ <br />4 　Statement stat = conn.createStatement(); <br />5 　ResultSet rs = stat.executeQuery( <br />6 　　"select uid, name from user"); <br />7 　while (rs.next()) <br />8 　{ <br />9 　　out.println("ID：" + rs.getString("uid") // ⑹ <br />10 　　　"，姓名：" + rs.getString("name")); <br />11 　} <br />12 　conn.close(); // ⑶ <br />13 　out.close(); <br />14 } <br />15 catch(Exception ex) // ⑵ <br />16 { <br />17 　ex.printStackTrace(); //⑴，⑷ <br />18 }</font></td></tr></tbody></table><p><br /><font size="2">　　作为一个Java程序员，你至少应该能够找出两个问题。但是，如果你不能找出全部六个问题，请继续阅读本文。 <br /><br />　　本文讨论的不是Java异常处理的一般性原则，因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”（anti-pattern）的违背优秀编码规范的常见坏习惯，帮助读者熟悉这些典型的反面例子，从而能够在实际工作中敏锐地察觉和避免这些问题。 <br /><br />　　<b>反例之一：丢弃异常 </b><br /><br />　　代码：15行-18行。 <br /><br />　　这段代码捕获了异常却不作任何处理，可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看，它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。如果你看到了这种丢弃（而不是抛出）异常的情况，可以百分之九十九地肯定代码存在问题（在极少数情况下，这段代码有存在的理由，但最好加上完整的注释，以免引起别人误解）。 <br /><br />　　这段代码的错误在于，异常（几乎）总是意味着某些事情不对劲了，或者说至少发生了某些不寻常的事情，我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上“处理异常”。不错，调用printStackTrace对调试程序有帮助，但程序调试阶段结束之后，printStackTrace就不应再在异常处理模块中担负主要责任了。 <br /><br />　　丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档，可以看到下面这段说明：“特别地，虽然出现ThreadDeath是一种‘正常的情形’，但ThreadDeath类是Error而不是Exception的子类，因为许多应用会捕获所有的Exception然后丢弃它不再理睬。”这段话的意思是，虽然ThreadDeath代表的是一种普通的问题，但鉴于许多应用会试图捕获所有异常然后不予以适当的处理，所以JDK把ThreadDeath定义成了Error的子类，因为Error类代表的是一般的应用不应该去捕获的严重问题。可见，丢弃异常这一坏习惯是如此常见，它甚至已经影响到了Java本身的设计。 <br /><br />　　那么，应该怎样改正呢？主要有四个选择： <br /><br />　　1、处理异常。针对该异常采取一些行动，例如修正问题、提醒某个人或进行其他一些处理，要根据具体的情形确定应该采取的动作。再次说明，调用printStackTrace算不上已经“处理好了异常”。 <br /><br />　　2、重新抛出异常。处理异常的代码在分析异常之后，认为自己不能处理它，重新抛出异常也不失为一种选择。 <br /><br />　　3、把该异常转换成另一种异常。大多数情况下，这是指把一个低级的异常转换成应用级的异常（其含义更容易被用户了解的异常）。 <br /><br />　　4、不要捕获异常。 <br /><br />　　结论一：既然捕获了异常，就要对它进行适当的处理。不要捕获异常之后又把它丢弃，不予理睬。 <br /><br />　　<b>反例之二：不指定具体的异常 </b><br /><br />　　代码：15行。 <br /><br />　　许多时候人们会被这样一种“美妙的”想法吸引：用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上，在绝大多数情况下，这种做法不值得提倡。为什么呢？ <br /><br />　　要理解其原因，我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常，而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生，catch(Exception ex)就相当于说我们想要处理几乎所有的异常。 <br /><br />　　再来看看前面的代码例子。我们真正想要捕获的异常是什么呢？最明显的一个是SQLException，这是JDBC操作中常见的异常。另一个可能的异常是IOException，因为它要操作OutputStreamWriter。显然，在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说，catch语句应当尽量指定具体的异常类型，而不应该指定涵盖范围太广的Exception类。 <br /><br />　　另一方面，除了这两个特定的异常，还有其他许多异常也可能出现。例如，如果由于某种原因，executeQuery返回了null，该怎么办？答案是让它们继续抛出，即不必捕获也不必处理。实际上，我们不能也不应该去捕获可能出现的所有异常，程序的其他地方还有捕获异常的机会??直至最后由JVM处理。 <br /><br />　　结论二：在catch语句中尽可能指定具体的异常类型，必要时使用多个catch。不要试图处理所有可能出现的异常。 <br /><br />　　<b>反例之三：占用资源不释放 </b><br /><br />　　代码：3行-14行。 <br /><br />　　异常改变了程序正常的执行流程。这个道理虽然简单，却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源，即使遇到了异常，也要正确释放占用的资源。为此，Java提供了一个简化这类操作的关键词finally。 <br /><br />　　finally是样好东西：不管是否出现了异常，Finally保证在try/catch/finally块结束之前，执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。 <br /><br />　　当然，编写finally块应当多加小心，特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会，尽量不要再有难以处理的错误。 <br /><br />　　结论三：保证所有资源都被正确释放。充分运用finally关键词。</font></p><p><font size="2"><strong>反例之四：不说明异常的详细信息 <br /><br /></strong>　　代码：3行-18行。 <br /><br />　　仔细观察这段代码：如果循环内部出现了异常，会发生什么事情？我们可以得到足够的信息判断循环内部出错的原因吗？不能。我们只能知道当前正在处理的类发生了某种错误，但却不能获得任何信息判断导致当前错误的原因。 <br /><br />　　printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程，但只提供了一些最基本的信息，未能说明实际导致错误的原因，同时也不易解读。 <br /><br />　　因此，在出现异常时，最好能够提供一些文字信息，例如当前正在执行的类、方法和其他状态信息，包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。 <br /><br />　　结论四：在异常处理模块中提供适量的错误原因信息，组织错误信息使其易于理解和阅读。 <br /><br />　　<b>反例之五：过于庞大的try块 </b><br /><br />　　代码：3行-14行。 <br /><br />　　经常可以看到有人把大量的代码放入单个try块，实际上这不是好习惯。这种现象之所以常见，原因就在于有些人图省事，不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子，虽然东西是带上了，但要找出来可不容易。 <br /><br />　　一些新手常常把大量的代码放入单个try块，然后再在catch语句中声明Exception，而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难，因为一大段代码中有太多的地方可能抛出Exception。 <br /><br />　　结论五：尽量减小try块的体积。 <br /><br />　　<b>反例之六：输出数据不完整</b><br /><br />　　代码：7行-11行。 <br /><br />　　不完整的数据是Java程序的隐形杀手。仔细观察这段代码，考虑一下如果循环的中间抛出了异常，会发生什么事情。循环的执行当然是要被打断的，其次，catch块会执行??就这些，再也没有其他动作了。已经输出的数据怎么办？使用这些数据的人或设备将收到一份不完整的（因而也是错误的）数据，却得不到任何有关这份数据是否完整的提示。对于有些系统来说，数据不完整可能比系统停止运行带来更大的损失。 <br /><br />　　较为理想的处置办法是向输出设备写一些信息，声明数据的不完整性；另一种可能有效的办法是，先缓冲要输出的数据，准备好全部数据之后再一次性输出。 <br /><br />　　结论六：全面考虑可能出现的异常以及这些异常对执行流程的影响。 <br /><br />　　<b>改写后的代码</b><br /><br />　　根据上面的讨论，下面给出改写后的代码。也许有人会说它稍微有点?嗦，但是它有了比较完备的异常处理机制。 <br /><br /></font></p><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td><font size="2">OutputStreamWriter out = ... <br />java.sql.Connection conn = ... <br />try { <br />　Statement stat = conn.createStatement(); <br />　ResultSet rs = stat.executeQuery( <br />　　"select uid, name from user"); <br />　while (rs.next()) <br />　{ <br />　　out.println("ID：" + rs.getString("uid") + "，姓名: " + rs.getString("name")); <br />　} <br />} <br />catch(SQLException sqlex) <br />{ <br />　out.println("警告：数据不完整"); <br />　throw new ApplicationException("读取数据时出现SQL错误", sqlex); <br />} <br />catch(IOException ioex) <br />{ <br />　throw new ApplicationException("写入数据时出现IO错误", ioex); <br />} <br />finally <br />{ <br />　if (conn != null) { <br />　　try { <br />　　　conn.close(); <br />　　} <br />　　catch(SQLException sqlex2) <br />　　{ <br />　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString()); <br />　　} <br />　} <br /><br />　if (out != null) { <br />　　try { <br />　　　out.close(); <br />　　} <br />　　catch(IOException ioex2) <br />　　{ <br />　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString()); <br />　　} <br />　} <br />} </font></td></tr></tbody></table><br /><font size="2">　　本文的结论不是放之四海皆准的教条，有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心，务必加上详细、全面的注释。 <br /><br />　　另一方面，不要笑话这些错误，不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途，原因很简单，因为它们确确实实带来了“方便”。所有这些反例都可以看作Java编程世界的恶魔，它们美丽动人，无孔不入，时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事，不足挂齿，但请记住：勿以恶小而为之，勿以善小而不为。 <br /></font></span>
<img src ="http://www.blogjava.net/cpsing/aggbug/85777.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cpsing/" target="_blank">cpsing</a> 2006-12-06 11:01 <a href="http://www.blogjava.net/cpsing/articles/85777.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>