ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>极品少妇一区二区三区精品视频,亚洲网一区二区三区,av成人动漫http://www.aygfsteel.com/cpsing/category/18113.htmlzh-cnWed, 28 Feb 2007 03:45:23 GMTWed, 28 Feb 2007 03:45:23 GMT60javascript 子窗å?父窗å?传值问é¢?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/cpsing/articles/94246.html</guid><wfw:comment>http://www.aygfsteel.com/cpsing/comments/94246.html</wfw:comment><comments>http://www.aygfsteel.com/cpsing/articles/94246.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cpsing/comments/commentRss/94246.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cpsing/services/trackbacks/94246.html</trackback:ping><description><![CDATA[ <p _fckxhtmljob="1">1. åˆäh–°çˆ¶çª—å?/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("","<script>window.showModalDial('scr,'','scroll:0;status:0;help:0;resizable:0;dialogWidth:530px;dialogHeight:350px');document.forms(0).Button2.click();</script>";);</font><br _fckxhtmljob="1" /></font>   </p> <p _fckxhtmljob="1"> </p> <img src ="http://www.aygfsteel.com/cpsing/aggbug/94246.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cpsing/" target="_blank">cpsing</a> 2007-01-16 17:13 <a href="http://www.aygfsteel.com/cpsing/articles/94246.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>异常处理框架-ZThttp://www.aygfsteel.com/cpsing/articles/85778.htmlcpsingcpsingWed, 06 Dec 2006 03:03:00 GMThttp://www.aygfsteel.com/cpsing/articles/85778.htmlhttp://www.aygfsteel.com/cpsing/comments/85778.htmlhttp://www.aygfsteel.com/cpsing/articles/85778.html#Feedback0http://www.aygfsteel.com/cpsing/comments/commentRss/85778.htmlhttp://www.aygfsteel.com/cpsing/services/trackbacks/85778.html

构徏更好的异常处理框�/h2> chris 发表�2005-03-13 12:00:00
作è€?McLaughlin     评论æ•?78 点击æ•?949     投票æ€Õd¾—åˆ?0 投票æ€ÖMh‹Æ?0
关键�

摘要:

åœ?EJB 最佛_®žè·ëŠš„˜q™ç¯‡ä¸“栏文章中,Brett McLaughlin è§£é‡Šäº†äØ“ä»€ä¹ˆå¯¹å¼‚å¸¸å¤„ç†æŠ•å…¥ä¸€ç‚¹å…³æ³¨å°±ä¼šç»™æˆ‘ä»¬å¸¦æ¥å¾ˆå¤§çš„å¸®åŠ©ï¼Œòq¶å‘您展½CÞZº†ä¸¤ç§½Ž€å•技术,它们ž®†å¸®åŠ©æ‚¨æ­£ç¡®åœ°æž„å»ºæ›´å¥å£®ä¸”æœ‰ç”¨çš„å¼‚å¸¸å¤„ç†æ¡†æž¶ã€?
企业应用½E‹åºåœ¨æž„建时常常对异常处理关注甚ž®‘,˜q™ä¼šé€ æˆå¯¹ä½Ž¾U§å¼‚常(å¦?java.rmi.RemoteException å’?javax.naming.NamingExceptionåQ‰çš„˜q‡åº¦ä¾èµ–。在 EJB 最佛_®žè·ëŠš„˜q™ç¯‡ä¸“栏文章中,Brett McLaughlin è§£é‡Šäº†äØ“ä»€ä¹ˆå¯¹å¼‚å¸¸å¤„ç†æŠ•å…¥ä¸€ç‚¹å…³æ³¨å°±ä¼šç»™æˆ‘ä»¬å¸¦æ¥å¾ˆå¤§çš„å¸®åŠ©ï¼Œòq¶å‘您展½CÞZº†ä¸¤ç§½Ž€å•技术,它们ž®†å¸®åŠ©æ‚¨æ­£ç¡®åœ°æž„å»ºæ›´å¥å£®ä¸”æœ‰ç”¨çš„å¼‚å¸¸å¤„ç†æ¡†æž¶ã€?br />
在本¾pÕdˆ—先前的技巧文章中åQŒå¼‚常处理不属于讨论的核心范围之内。但是,您可能会发现一点,那就是我们一直都回避来自 Web 层的低çñ”异常。我们向客户机提供诸å¦?ApplicationException å’?InvalidDataException 之类的异常,而没有让 Web 层处理象 java.rmi.RemoteException æˆ?javax.naming.NamingException ˜q™æ ·çš„异常ã€?br />
˜qœç¨‹å’Œå‘½åå¼‚常是¾pȝ»Ÿ¾U§å¼‚常,而应用程序和非法数据异常是业务çñ”异常åQŒå› ä¸ºå®ƒä»¬æäº¤æ›´é€‚用的业务信息。当军_®šæŠ›å‡ºä½•种¾cÕdž‹çš„异常时åQŒæ‚¨åº”该æ€ÀL˜¯é¦–先考虑ž®†è¦å¤„理所报告异常的层。Web 层通常是由执行业务ä»ÕdŠ¡çš„æœ€¾lˆç”¨æˆ·é©±åŠ¨çš„åQŒæ‰€ä»¥æœ€å¥½ç”¨å®ƒå¤„理业务çñ”异常。但是,åœ?EJB 层,您正在执行系¾lŸçñ”ä»ÕdŠ¡åQŒå¦‚使用 JNDI 或数据库。尽½Ž¡è¿™äº›ä“Q务最¾lˆå°†è¢«åˆòq¶åˆ°ä¸šåŠ¡é€»è¾‘ä¸­ï¼Œä½†æ˜¯æœ€å¥½ç”¨è¯¸å¦‚ RemoteException 之类的系¾lŸçñ”异常来表½Cºå®ƒä»¬ã€?br />
理论上,您可以让所æœ?Web 层方法预期处理和响应单个应用½E‹åºå¼‚常åQŒæ­£å¦‚我们在先前的一些示例中所做的一栗÷€‚但˜q™ç§æ–ÒŽ³•不适用于长旉™—´˜qè¡Œã€‚让您的委派æ–ÒŽ³•抛出更具体的异常åQŒè¿™æ˜¯ä¸€ä¸ªå¥½å¾—多的异常处理方案,从根本上è®ÔŒ¼Œ˜q™å¯¹æŽ¥æ”¶å®¢æˆ·æœºæ›´æœ‰ç”¨ã€‚在˜q™ç¯‡æŠ€å·§æ–‡ç« ä¸­åQŒæˆ‘们将讨论两种技术,它们ž®†æœ‰åŠ©äºŽæ‚¨åˆ›å»ÞZ¿¡æ¯æ›´ä¸°å¯Œã€æ›´å…·ä½“的异常,而不会生成大量不必要的代码ã€?br />
嵌套的异�/b>
在设计可靠的异常处理æ–ÒŽ¡ˆæ—Óž¼Œè¦è€ƒè™‘的第一件事情就是对所谓的低çñ”或系¾lŸçñ”异常˜q›è¡ŒæŠ½è±¡åŒ–。这些核å¿?Java 异常通常会报告网¾lœæµé‡ä¸­çš„错误、JNDI æˆ?RMI 问题åQŒæˆ–者是应用½E‹åºä¸­çš„其它技术问题。RemoteException、EJBException å’?NamingException 是企ä¸?Java ¾~–程中低¾U§å¼‚常的常见例子ã€?br />
˜q™äº›å¼‚常完全没有ä»ÖM½•意义åQŒç”± Web 层的客户机接收时ž®¤å…¶å®ÒŽ˜“æ·äh·†ã€‚如果客æˆähœºè°ƒç”¨ purchase() òq¶æŽ¥æ”¶åˆ° NamingExceptionåQŒé‚£ä¹ˆå®ƒåœ¨è§£å†Œ™¿™ä¸ªå¼‚常时会一½{¹èŽ«å±•ã€‚åŒæ—Óž¼Œåº”用½E‹åºä»£ç å¯èƒ½éœ€è¦è®¿é—®è¿™äº›å¼‚叿€¸­çš„信息,因此不能è½ÀL˜“地抛弃或忽略它们ã€?br />
½{”案是提供一¾cÀL›´æœ‰ç”¨çš„异常,它还包含低çñ”异常。清å?1 æ¼”ç¤ºäº†ä¸€ä¸ªä¸“ä¸ø™¿™ä¸€ç‚¹è®¾è®¡çš„½Ž€å?ApplicationExceptionåQ?br />
清单 1. 嵌套的异�package com.ibm;
import java.io.PrintStream;
import java.io.PrintWriter;
public class ApplicationException extends Exception {
       /** A wrapped Throwable */
       protected Throwable cause;
       public ApplicationException() {
           super("Error occurred in application.");
       }
       public ApplicationException(String message)  {
           super(message);
       }
       public ApplicationException(String message, Throwable cause)  {
           super(message);
           this.cause = cause;
       }
       // Created to match the JDK 1.4 Throwable method.
       public Throwable initCause(Throwable cause)  {
           this.cause = cause;
           return cause;
       }
       public String getMessage() {
           // Get this exception's message.
           String msg = super.getMessage();
           Throwable parent = this;
           Throwable child;
           // Look for nested exceptions.
           while((child = getNestedException(parent)) != null) {
               // Get the child's message.
               String msg2 = child.getMessage();
               // If we found a message for the child exception,
               // we append it.
               if (msg2 != null) {
                   if (msg != null) {
                       msg += ": " + msg2;
                   } else {
                       msg = msg2;
                   }
               }
               // Any nested ApplicationException will append its own
               // children, so we need to break out of here.
               if (child instanceof ApplicationException) {
                   break;
               }
               parent = child;
           }
           // Return the completed message.
           return msg;
       }
       public void printStackTrace() {
           // Print the stack trace for this exception.
           super.printStackTrace();
           Throwable parent = this;
           Throwable child;
           // Print the stack trace for each nested exception.
           while((child = getNestedException(parent)) != null) {
               if (child != null) {
                   System.err.print("Caused by: ");
                   child.printStackTrace();
                   if (child instanceof ApplicationException) {
                       break;
                   }
                   parent = child;
               }
           }
       }
       public void printStackTrace(PrintStream s) {
           // Print the stack trace for this exception.
           super.printStackTrace(s);
           Throwable parent = this;
           Throwable child;
           // Print the stack trace for each nested exception.
           while((child = getNestedException(parent)) != null) {
               if (child != null) {
                   s.print("Caused by: ");
                   child.printStackTrace(s);
                   if (child instanceof ApplicationException) {
                       break;
                   }
                   parent = child;
               }
           }
       }
       public void printStackTrace(PrintWriter w) {
           // Print the stack trace for this exception.
           super.printStackTrace(w);
           Throwable parent = this;
           Throwable child;
           // Print the stack trace for each nested exception.
           while((child = getNestedException(parent)) != null) {
               if (child != null) {
                   w.print("Caused by: ");
                   child.printStackTrace(w);
                   if (child instanceof ApplicationException) {
                       break;
                   }
                   parent = child;
               }
           }
       }
       public Throwable getCause()  {
           return cause;
       }
}






清单 1 中的代码很简单;我们已经½Ž€å•地ž®†å¤šä¸ªå¼‚å¸¸â€œä¸²â€åœ¨ä¸€èµøP¼Œä»¥åˆ›å»ºå•个、嵌套的异常。但是,真正的好处在于将˜q™ç§æŠ€æœ¯ä½œä¸ºå‡ºå‘点åQŒä»¥åˆ›å¾ç‰¹å®šäºŽåº”用程序的异常层次¾l“构。异常层‹Æ¡ç»“构将允许 EJB 客户机既接收特定于业务的异常也接收特定于¾pȝ»Ÿçš„信息,而不需要编写大量额外代码ã€?br />
异常层次¾l“æž„
异常层次¾l“构应该从一些十分健壮而又通用的异常入手,å¦?ApplicationException。如果您ž®†é¡¶¾U§å¼‚常搞得太具体åQŒé‚£ä¹ˆå…¶¾l“果是您今后ž®†ä¸å¾—不重新构造层‹Æ¡ç»“构,以适应某些较通用的情å†üc€?br />
å› æ­¤åQŒè®©æˆ‘们假定您的应用½E‹åºè¦æ±‚ NoSuchBookException、InsufficientFundsException å’?SystemUnavailableException。您不必创徏˜q™ä¸‰ä¸ªå¼‚常,让它们ç‘ôæ‰?ApplicationExceptionåQŒç„¶åŽåªéœ€æä¾›æžå°‘几个必须的构造器来创建格式化的消息。清å?2 是此¾cÕd¼‚常层‹Æ¡ç»“构的½CÞZ¾‹åQ?br />
清单 2. 异常层次¾l“æž„ package com.ibm.library;
import com.ibm.ApplicationException;
public class NoSuchBookException extends ApplicationException {
       public NoSuchBookException(String bookName, String libraryName) {
        super("The book '" + bookName + "' was not found in the '" +
            libraryName + "' library.");
    }
}





当需要编写大量专用异常时åQŒå¼‚常层‹Æ¡ç»“构极大地½Ž€åŒ–了工作。对于一个异常,为每个异常类æ·ÕdŠ ä¸€ä¸ªæˆ–ä¸¤ä¸ªæž„é€ å™¨åQŒæ‰€èŠÞp´¹æ—‰™—´å¾ˆå°‘不超˜q‡å‡ åˆ†é’Ÿã€‚您˜q˜ç»å¸”Rœ€è¦ç»™˜q™äº›æ›´å…·ä½“的异常åQˆè¿™äº›å¼‚叿€¹Ÿæ˜¯ä¸»åº”用½E‹åºå¼‚常的子¾c»ï¼‰æä¾›å­ç±»åQŒä»¥æä¾›æ›´å…·ä½“的异常。例如,您可能需è¦?InvalidTitleException å’?BackorderedException 来ç‘ôæ‰?NoSuchBookExceptionã€?br />
企业应用½E‹åºåœ¨æž„建时通常都不会注意异常处理。尽½Ž¡ä¾é ä½Ž¾U§å¼‚常(å¦?RemoteException å’?NamingExceptionåQ‰å¾ˆå®ÒŽ˜“åQˆæœ‰æ—¶ä¹Ÿå¾ˆè¯±äººï¼‰åQŒä½†å¦‚果一开始就建立一个可靠的、深思熟虑的异常模型åQŒåˆ™æ‚¨å°†åœ¨åº”用程序上ž®‘花很多¾_‘ÖŠ›ã€‚创å»ÞZ¸€ä¸ªåµŒå¥—的、层‹Æ¡ç»“构化的异常框架将改进代码的可è¯ÀL€§åŠå…¶å¯ç”¨æ€§ã€?br />

关于作è€?br />Brett McLaughlin ä»?Logo 时代åQˆè¿˜è®°å¾—那个ž®ä¸‰è§’吗åQŸï¼‰ž®±å¼€å§‹ä»Žäº‹è®¡½Ž—机工作了。他现在专门研究ç”?Java å’?Java 相关技术构建应用程序基¼‹€¾l“构。过åŽÕd‡ òq´ä»–一直在 Nextel Communications å’?Allegiance Telecom, Inc. 致力于实现这些基¼‹€¾l“构。Brett æ˜?Java Apache ™å¹ç›® Turbine 的共同创始äh之一åQŒè¯¥™å¹ç›®ä¸ÞZ‹Éç”?Java servlet çš?Web 应用½E‹åºå¼€å‘构建可重用的组件体¾pȝ»“构。他˜q˜æ˜¯ EJBoss ™å¹ç›®åQˆä¸€ä¸ªå¼€æ”¾æºç ?EJB 应用½E‹åºæœåŠ¡å™¨ï¼‰å’?CocoonåQˆä¸€ä¸ªå¼€æ”¾æºç ?XML Web 发布引擎åQ‰çš„志愿开发äh员之一。可通过 brett@oreilly.com ä¸?Brett 联系ã€?


]]>Java异常处理技�ZThttp://www.aygfsteel.com/cpsing/articles/85777.htmlcpsingcpsingWed, 06 Dec 2006 03:01:00 GMThttp://www.aygfsteel.com/cpsing/articles/85777.htmlhttp://www.aygfsteel.com/cpsing/comments/85777.htmlhttp://www.aygfsteel.com/cpsing/articles/85777.html#Feedback0http://www.aygfsteel.com/cpsing/comments/commentRss/85777.htmlhttp://www.aygfsteel.com/cpsing/services/trackbacks/85777.html 

六种异常处理的陋�/font>

你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机åˆÓž¼Ÿåœ¨ä¸‹é¢è¿™ŒDµä»£ç ä¸­åQŒä½ èƒ½å¤Ÿ˜q…速找出异常处理的六个问题吗?

1 OutputStreamWriter out = ...
2 java.sql.Connection conn = ...
3 try { // â‘?
4  Statement stat = conn.createStatement();
5  ResultSet rs = stat.executeQuery(
6   "select uid, name from user");
7  while (rs.next())
8  {
9   out.println("IDåQ? + rs.getString("uid") // â‘?
10    "åQŒå§“名:" + rs.getString("name"));
11  }
12  conn.close(); // �
13  out.close();
14 }
15 catch(Exception ex) // â‘?
16 {
17  ex.printStackTrace(); //â‘ß_¼Œâ‘?
18 }


ã€€ã€€ä½œäØ“ä¸€ä¸ªJava½E‹åºå‘˜ï¼Œä½ è‡³ž®‘应该能够找å‡ÞZ¸¤ä¸ªé—®é¢˜ã€‚但是,如果你不能找出全部六个问题,è¯ïL‘ô¾l­é˜…è¯ÀLœ¬æ–‡ã€?

  本文讨论的不是Javaå¼‚å¸¸å¤„ç†çš„ä¸€èˆ¬æ€§åŽŸåˆ™ï¼Œå› äØ“˜q™äº›åŽŸåˆ™å·²ç»è¢«å¤§å¤šæ•°äººç†ŸçŸ¥ã€‚æˆ‘ä»¬è¦åšçš„æ˜¯åˆ†æžå„¿Uå¯¿UîCؓ“反例”(anti-patternåQ‰çš„˜qèƒŒä¼˜ç§€¾~–码规范的常见坏习惯åQŒå¸®åŠ©è¯»è€…ç†Ÿæ‚‰è¿™äº›å…¸åž‹çš„åé¢ä¾‹å­åQŒä»Žè€Œèƒ½å¤Ÿåœ¨å®žé™…工作中敏锐地察觉和避免这些问题ã€?

  反例之一åQšä¸¢å¼ƒå¼‚å¸?

  代码åQ?5è¡?18行ã€?

  ˜q™æ®µä»£ç æ•获了异常却不作ä»ÖM½•处理åQŒå¯ä»¥ç®—得上Java¾~–程中的杀手。从问题出现的频¾Jç¨‹åº¦å’Œ¼œ¸å®³½E‹åº¦æ¥çœ‹åQŒå®ƒä¹Ÿè®¸å¯ä»¥å’ŒC/C++½E‹åºçš„一个恶名远播的问题相提òq¶è®º??不检查缓冲区是否已满。如果你看到了这¿Uä¸¢å¼ƒï¼ˆè€Œä¸æ˜¯æŠ›å‡ºï¼‰å¼‚常的情况,可以癑ֈ†ä¹‹ä¹åä¹åœ°è‚¯å®šä»£ç å­˜åœ¨é—®é¢˜ï¼ˆåœ¨æžž®‘数情况下,˜q™æ®µä»£ç æœ‰å­˜åœ¨çš„理由åQŒä½†æœ€å¥½åŠ ä¸Šå®Œæ•´çš„æ³¨é‡ŠåQŒä»¥å…å¼•èµ·åˆ«äºø™¯¯è§£ï¼‰ã€?

  ˜q™æ®µä»£ç çš„错误在于,异常åQˆå‡ ä¹Žï¼‰æ€ÀL˜¯æ„å‘³ç€æŸäº›äº‹æƒ…不对劲了åQŒæˆ–者说臛_°‘发生了某些不å¯Õd¸¸çš„事情,我们不应该对½E‹åºå‘出的求救信号保持沉默和无动于衷。调用一下printStackTrace½Ž—不上“处理异常”。不错,调用printStackTrace对调试程序有帮助åQŒä½†½E‹åºè°ƒè¯•阶段¾l“束之后åQŒprintStackTracež®×ƒ¸åº”再在异常处理模块中担负主要责ä“Q了ã€?

  丢弃异常的情形非常普遍。打开JDKçš„ThreadDeath¾cÈš„æ–‡æ¡£åQŒå¯ä»¥çœ‹åˆîC¸‹é¢è¿™ŒDµè¯´æ˜Žï¼šâ€œç‰¹åˆ«åœ°åQŒè™½ç„¶å‡ºçްThreadDeath是一¿Uâ€˜æ­£å¸¸çš„æƒ…åŞ’,但ThreadDeath¾cÀL˜¯Error而不是Exception的子¾c»ï¼Œå› äؓ许多应用会捕èŽäh‰€æœ‰çš„Exception然后丢弃它不再理睬。”这ŒDµè¯çš„æ„æ€æ˜¯åQŒè™½ç„¶ThreadDeath代表的是一¿Uæ™®é€šçš„问题åQŒä½†é‰´äºŽè®¸å¤šåº”用会试图捕èŽäh‰€æœ‰å¼‚常然后不予以适当的处理,所以JDK把ThreadDeath定义成了Error的子¾c»ï¼Œå› äØ“Error¾cÖM»£è¡¨çš„æ˜¯ä¸€èˆ¬çš„应用不应该去捕获的严重问题。可见,丢弃异常˜q™ä¸€åä¹ æƒ¯æ˜¯å¦‚此常见åQŒå®ƒç”šè‡³å·²ç»å½±å“åˆîCº†Java本èín的设计ã€?

  那么åQŒåº”该怎样æ”ÒŽ­£å‘¢ï¼Ÿä¸»è¦æœ‰å››ä¸ªé€‰æ‹©åQ?

  1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个äh或进行其他一些处理,要根据具体的情åÅž¼‹®å®šåº”该采取的动作。再‹Æ¡è¯´æ˜Žï¼Œè°ƒç”¨printStackTrace½Ž—不上已¾lâ€œå¤„理好了异常”ã€?

  2ã€é‡æ–°æŠ›å‡ºå¼‚å¸¸ã€‚å¤„ç†å¼‚å¸¸çš„ä»£ç åœ¨åˆ†æžå¼‚å¸æ€¹‹åŽï¼Œè®¤äؓ自己不能处理它,重新抛出异常也不å¤×ƒØ“一¿Ué€‰æ‹©ã€?

  3、把该异常è{换成另一¿Uå¼‚常。大多数情况下,˜q™æ˜¯æŒ‡æŠŠä¸€ä¸ªä½Ž¾U§çš„异常转换成应用çñ”的异常(其含义更å®ÒŽ˜“被用户了解的异常åQ‰ã€?

  4、不要捕获异常�

  ¾l“论一åQšæ—¢ç„¶æ•èŽ·äº†å¼‚å¸¸åQŒå°±è¦å¯¹å®ƒè¿›è¡Œé€‚å½“çš„å¤„ç†ã€‚ä¸è¦æ•èŽ·å¼‚å¸æ€¹‹åŽåˆæŠŠå®ƒä¸¢å¼ƒåQŒä¸äºˆç†ç¬ã€?

  反例之二åQšä¸æŒ‡å®šå…·ä½“的异å¸?

  代码åQ?5行ã€?

  许多时候äh们会被这样一¿Uâ€œç¾Žå¦™çš„”想法吸引:用一个catch语句捕获所有的异常。最常见的情形就是ä‹É用catch(Exception ex)语句。但实际上,在绝大多数情况下åQŒè¿™¿Uåšæ³•ä¸å€¼å¾—æå€¡ã€‚äØ“ä»€ä¹ˆå‘¢åQ?

  要理解其原因åQŒæˆ‘们必™åÕd›ž™å¾ä¸€ä¸‹catch语句的用途。catch语句表示我们预期会出现某¿Uå¼‚常,而且希望能够处理该异常。异常类的作用就是告诉Java¾~–译器我们想要处理的是哪一¿Uå¼‚常。由于绝大多数异帔Rƒ½ç›´æŽ¥æˆ–间接从java.lang.Exception‹z„¡”ŸåQŒcatch(Exception ex)ž®Þq›¸å½“于说我们想要处理几乎所有的异常ã€?

  再来看看前面的代码例子。我们真正想要捕èŽïLš„异常是什么呢åQŸæœ€æ˜Žæ˜¾çš„一个是SQLExceptionåQŒè¿™æ˜¯JDBC操作中常见的异常。另一个可能的异常是IOExceptionåQŒå› ä¸ºå®ƒè¦æ“ä½œOutputStreamWriter。显ç„Óž¼Œåœ¨åŒä¸€ä¸ªcatch块中处理˜q™ä¸¤¿Uæˆªç„¶ä¸åŒçš„异常是不合适的。如果用两个catch块分别捕获SQLExceptionå’ŒIOExceptionž®Þp¦å¥½å¤šäº†ã€‚è¿™ž®±æ˜¯è¯ß_¼Œcatch语句应当ž®½é‡æŒ‡å®šå…·ä½“的异常类型,而不应该指定æ¶ëŠ›–范围太广的Exception¾c…R€?

  另一斚w¢åQŒé™¤äº†è¿™ä¸¤ä¸ªç‰¹å®šçš„异常,˜q˜æœ‰å…¶ä»–许多异常也可能出现。例如,如果ç”׃ºŽæŸç§åŽŸå› åQŒexecuteQuery˜q”回了nullåQŒè¯¥æ€Žä¹ˆåŠžï¼Ÿ½{”案是让它们¾l§ç®‹æŠ›å‡ºåQŒå³ä¸å¿…捕获也不必处理。实际上åQŒæˆ‘们不能也不应该去捕获可能出现的所有异常,½E‹åºçš„其他地方还有捕获异常的æœÞZ¼š??直至最后由JVM处理ã€?

  ¾l“论二:在catch语句中尽可能指定具体的异常类型,必要时ä‹É用多个catch。不要试囑֤„理所有可能出现的异常ã€?

  反例之三åQšå ç”¨èµ„源不释放

  代码åQ?è¡?14行ã€?

  异常改变了程序正常的执行‹¹ç¨‹ã€‚这个道理虽然简单,却常常被äºÞZ»¬å¿½è§†ã€‚如果程序用åˆîCº†æ–‡äšg、Socket、JDBC˜qžæŽ¥ä¹‹ç±»çš„资源,即ä‹Éé‡åˆ°äº†å¼‚å¸¸ï¼Œä¹Ÿè¦æ­£ç¡®é‡Šæ”¾å ç”¨çš„èµ„æºã€‚äØ“æ­¤ï¼ŒJava提供了一个简化这¾cÀL“ä½œçš„关键词finallyã€?

  finally是样好东西:不管是否出现了异常,Finally保证在try/catch/finally块结束之前,执行清理ä»ÕdŠ¡çš„ä»£ç æ€ÀL˜¯æœ‰æœºä¼šæ‰§è¡Œã€‚遗憄¡š„是有些äh却不习惯使用finallyã€?

  当然åQŒç¼–写finally块应当多加小心,特别是要注意在finally块之内抛出的异常??˜q™æ˜¯æ‰§è¡Œæ¸…理ä»ÕdŠ¡çš„æœ€åŽæœºä¼šï¼Œž®½é‡ä¸è¦å†æœ‰éš¾ä»¥å¤„理的错误ã€?

  ¾l“论三:保证所有资源都被正¼‹®é‡Šæ”¾ã€‚充分运用finally关键词ã€?/font>

反例之四åQšä¸è¯´æ˜Žå¼‚常的详¾l†ä¿¡æ?

  代码åQ?è¡?18行ã€?

  仔细观察˜q™æ®µä»£ç åQšå¦‚æžœåó@环内部出çŽîCº†å¼‚常åQŒä¼šå‘生什么事情?我们可以得到­‘›_¤Ÿçš„信息判断åó@环内部出错的原因吗?不能。我们只能知道当前正在处理的¾cÕd‘生了某种错误åQŒä½†å´ä¸èƒ½èŽ·å¾—ä“Q何信息判断导致当前错误的原因ã€?

  printStackTrace的堆栈跟ítªåŠŸèƒ½æ˜¾½Cºå‡º½E‹åº˜qè¡Œåˆ°å½“前类的执行流½E‹ï¼Œä½†åªæä¾›äº†ä¸€äº›æœ€åŸºæœ¬çš„ä¿¡æ¯ï¼Œæœªèƒ½è¯´æ˜Žå®žé™…å¯ÆD‡´é”™è¯¯çš„原因,同时也不易解诅R€?

  因此åQŒåœ¨å‡ºçް异叏æ—Óž¼Œæœ€å¥½èƒ½å¤Ÿæä¾›ä¸€äº›æ–‡å­—信息,例如当前正在执行的类、方法和其他状态信息,包括以一¿Uæ›´é€‚合阅读的方式整理和¾l„织printStackTrace提供的信息ã€?

  ¾l“论四:在异常处理模块中提供适量的错误原因信息,¾l„织错误信息使其易于理解和阅诅R€?

  反例之五åQšè¿‡äºŽåºžå¤§çš„tryå?

  代码åQ?è¡?14行ã€?

  ¾lå¸¸å¯ä»¥çœ‹åˆ°æœ‰äh把大量的代码攑օ¥å•个try块,实际上这不是好习惯。这¿UçŽ°è±¡ä¹‹æ‰€ä»¥å¸¸è§ï¼ŒåŽŸå› ž®±åœ¨äºŽæœ‰äº›äh囄¡œäº‹ï¼Œä¸æ„¿èŠ±æ—¶é—´åˆ†æžä¸€å¤§å—ä»£ç ä¸­å“ªå‡ è¡Œä»£ç ä¼šæŠ›å‡ºå¼‚å¸¸ã€å¼‚å¸¸çš„å…·ä½“¾cÕdž‹æ˜¯ä»€ä¹ˆã€‚把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大½Ž±å­åQŒè™½ç„¶ä¸œè¥¿æ˜¯å¸¦ä¸Šäº†ï¼Œä½†è¦æ‰‘Ö‡ºæ¥å¯ä¸å®¹æ˜“ã€?

  一些新手常常把大量的代码放入单个try块,然后再在catch语句中声明ExceptionåQŒè€Œä¸æ˜¯åˆ†¼›Õd„个可能出现异常的ŒDµè½òq¶åˆ†åˆ«æ•获其异常。这¿Uåšæ³•äØ“åˆ†æž½E‹åºæŠ›å‡ºå¼‚常的原因带来了困难åQŒå› ä¸ÞZ¸€å¤§æ®µä»£ç ä¸­æœ‰å¤ªå¤šçš„地方可能抛出Exceptionã€?

  ¾l“论五:ž®½é‡å‡å°try块的体积ã€?

  反例之六åQšè¾“出数据不完整

  代码åQ?è¡?11行ã€?

  不完整的数据是Java½E‹åºçš„隐形杀手。仔¾l†è§‚察这ŒDµä»£ç ï¼Œè€ƒè™‘一下如果åó@环的中间抛出了异常,会发生什么事情。åó@环的执行当然是要被打断的åQŒå…¶‹Æ¡ï¼Œcatch块会执行??ž®Þp¿™äº›ï¼Œå†ä¹Ÿæ²¡æœ‰å…¶ä»–动作了。已¾lè¾“出的数据怎么办?使用˜q™äº›æ•°æ®çš„äh或设备将收到一份不完整的(因而也是错误的åQ‰æ•°æ®ï¼Œå´å¾—不到ä»ÖM½•有关˜q™ä†¾æ•°æ®æ˜¯å¦å®Œæ•´çš„æ½Cºã€‚对于有些系¾lŸæ¥è¯ß_¼Œæ•°æ®ä¸å®Œæ•´å¯èƒ½æ¯”¾pȝ»Ÿåœæ­¢˜qè¡Œå¸¦æ¥æ›´å¤§çš„æŸå¤±ã€?

ã€€ã€€è¾ƒäØ“ç†æƒ³çš„å¤„¾|®åŠžæ³•æ˜¯å‘è¾“å‡ø™®¾å¤‡å†™ä¸€äº›ä¿¡æ¯ï¼Œå£°æ˜Žæ•°æ®çš„不完整性;另一¿Uå¯èƒ½æœ‰æ•ˆçš„办法是,先缓冲要输出的数据,准备好全部数据之后再一‹Æ¡æ€§è¾“出ã€?

  ¾l“è®ºå…­ï¼šå…¨é¢è€ƒè™‘å¯èƒ½å‡ºçŽ°çš„å¼‚å¸æ€»¥åŠè¿™äº›å¼‚常对执行‹¹ç¨‹çš„媄响ã€?

  改写后的代码

  æ ÒŽ®ä¸Šé¢çš„讨论,下面¾l™å‡ºæ”¹å†™åŽçš„代码。也许有äºÞZ¼šè¯´å®ƒ½Eå¾®æœ‰ç‚¹?嗦,但是它有了比较完备的异常处理机制ã€?

OutputStreamWriter out = ...
java.sql.Connection conn = ...
try {
 Statement stat = conn.createStatement();
 ResultSet rs = stat.executeQuery(
  "select uid, name from user");
 while (rs.next())
 {
  out.println("IDåQ? + rs.getString("uid") + "åQŒå§“å? " + rs.getString("name"));
 }
}
catch(SQLException sqlex)
{
 out.println("警告åQšæ•°æ®ä¸å®Œæ•´");
 throw new ApplicationException("è¯Õd–数据时出现SQL错误", sqlex);
}
catch(IOException ioex)
{
 throw new ApplicationException("写入数据时出现IO错误", ioex);
}
finally
{
 if (conn != null) {
  try {
   conn.close();
  }
  catch(SQLException sqlex2)
  {
   System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连� " + sqlex2.toString());
  }
 }

 if (out != null) {
  try {
   out.close();
  }
  catch(IOException ioex2)
  {
   System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文äšg" + ioex2.toString());
  }
 }
}

  本文的结è®ÞZ¸æ˜¯æ”¾ä¹‹å››‹¹ïLš†å‡†çš„æ•™æ¡åQŒæœ‰æ—¶å¸¸è¯†å’Œ¾léªŒæ‰æ˜¯æœ€å¥½çš„老师。如果你对自å·Þqš„做法没有癑ֈ†ä¹‹ç™¾çš„信心,务必加上详细、全面的注释ã€?

  另一斚w¢åQŒä¸è¦ç¬‘话这些错误,不妨问问你自己是否真地彻底摆è„׃º†˜q™äº›åä¹ æƒ¯ã€‚即使最有经验的½E‹åºå‘˜å¶ž®”ä¹Ÿä¼šè¯¯å…¥æ­§é€”ï¼ŒåŽŸå› å¾ˆç®€å•ï¼Œå› äØ“å®ƒä»¬¼‹®ç¡®å®žå®žå¸¦æ¥äº†â€œæ–¹ä¾Žì€ã€‚所有这些反例都可以看作Java¾~–程世界的恶™ì”,它们¾ŸŽä¸½åЍähåQŒæ— å­”不入,时刻诱惑着你。也许有äºÞZ¼šè®¤äØ“˜q™äº›éƒ½å±žäºŽé¸¡çš®è’œæ¯›çš„ž®äº‹åQŒä¸­‘ÏxŒ‚齿,但请è®îC½åQšå‹¿ä»¥æ¶ž®è€Œäؓ之,勿以善小而不为ã€?


]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÆÕ°²ÏØ| ³¤ÎäÏØ| Àû´¨ÊÐ| ÍþÔ¶ÏØ| Õò°ÍÏØ| ÂÛ̳| ÔªÊÏÏØ| ºº¹ÁÇø| ºìºÓÏØ| ÎäÆ½ÏØ| ÉÌÄÏÏØ| ³¤¸ðÊÐ| ÍÁÄ¬ÌØ×óÆì| Ôý´ïÏØ| Ä®ºÓÏØ| ãë´¨ÏØ| ¶«É½ÏØ| ³¤ÊÙÇø| ÍÐÀïÏØ| ¸»Ô£ÏØ| µÂ»¯ÏØ| ´¾°²ÏØ| ʯÇþÏØ| ¹ã¶«Ê¡| ¹ãººÊÐ| äÓÆÖÏØ| À´±öÊÐ| Ë®³ÇÏØ| ÎàÖÝÊÐ| Áú´¨ÏØ| ÒË´ºÊÐ| ˳ÒåÇø| Ä˶«ÏØ| ¸£¶¦ÊÐ| »¯Â¡| ̨±±ÊÐ| °²Î÷ÏØ| ÑÎÍ¤ÏØ| ·ÚÑôÊÐ| ÂêÇúÏØ| ËçÀâÏØ|