程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 捕捉未捕獲的異常

捕捉未捕獲的異常

編輯:JAVA編程入門知識

原文地址:http://Java.sun.com/developer/JDCTechTips/2006/tt0211.Html#2

日期:<?XML:namespace prefix = st1 ns = "urn:schemas-microsoft-com:Office:smarttags" />2006-02-11

 

2004年3月16日的技術技巧Best Practices in Exception Handling講述了幾個處理異常的最好實踐。在該技巧中,你將學習另外一個處理異常的方法。我們是通過J2SE 5.0 新增的UncaughtExceptionHandler接口來處理。

       UncaughtExceptionHandler名字意味著處理未捕捉的異常。更明確的說,它處理未捕捉的運行時異常。Java編譯器要求處理所有非運行時異常,否則程序不能編譯通過。這裡“處理”的是方法裡throws子句聲明的異常或在try-catch塊裡的catch子句的異常。

       在下面的示例中,讓我們關注兩個異常:FileNotFoundException和ArithmeticException。假如使用一個不正確的String或File參數值來構造FileReader時,將會拋出FileNotFoundException異常。當你調用這些構造函數時,編譯器要求你處理每一個可能拋出異常的子句:

 

FileReader input;

   String filename = ...;

   try {

     input = new FileReader(filename);

   } catch (FileNotFoundException e) {

     processMissingFile(filename, e);

   }

      

我們再來比較一下,ArithmeticException是一個運行時異常。Java編程語言規范(對於編譯器而言)不要求處理運行時異常。因此在下面的循環中,從10到0都會被100除,而在最後一次循環中將拋出ArithmeticException異常:

 

for (int i=10; i >= 0; i--) {

     int div = 100 / i;


  

   }

 

   Exception in thread "main" java.lang.ArithmeticException: /

   by zero

        at Test.main(Test.java:4)

      

輸出堆棧信息顯示出缺省未捕捉的異常內容。通常說來,這樣的缺省行為已經足夠了,不過有時也不行。設想你想在彈出式窗口輸出堆棧信息,來替代在系統控制台輸出該信息。假如你自己設置一個缺省的未捕捉異常處理,你就可以得到這樣的效果。

       這裡有三個最新的處理未捕捉異常的方法。第一,你可以調用Thread的setUncaughtExceptionHandler()方法。這個方法答應你在非凡的線程裡定制行為。第二,你可以定義你自己的ThreadGroup並改變行為使每個線程都從這個組中創建並重寫它們的uncaughtException()方法。第三,你可以設置缺省行為讓所有線程調用Thread的靜態方法setDefaultUncaughtExceptionHandler()。

       Thread的setUncaughtExceptionHandler()和setDefaultUncaughtExceptionHandler()方法都需要實現UncaughtExceptionHandler接口作為參數。該接口是Thread類的內部接口,因此它的全名是Thread.UncaughtExceptionHandler。該接口的唯一方法是:

 

void uncaughtException(Thread t, Throwable e)

 

當你實現了uncaughtException方法或實現了該接口或重寫ThreadGroup的方法,你都可以定制其行為。在下面的示例中,我們實現了UncaughtExceptionHandler,無論運行時異常何時發生,堆棧信息都會顯示在窗口的文本區域裡。你可以在兩個異常間關閉窗口。當下次異常發生時,窗口會再次出現在其他窗口之前。

 

   import java.awt.*;

   import java.io.*;

   import javax.swing.*;

 

   public class StackWindow extends JFrame

       implements Thread.UncaughtExceptionHandler {

 

     private JTextArea textArea;

 

     public StackWindow(

      String title, final int width, final int height) {

       super(title);

       setSize(width, height);


  

       textArea = new JTextArea();

       JScrollPane pane = new JScrollPane(textArea);

       textArea.setEditable(false);

       getContentPane().add(pane);

     }

 

     public void uncaughtException(Thread t, Throwable e) {

       addStackInfo(e);

     }

 

     public void addStackInfo(final Throwable t) {

       EventQueue.invokeLater(new Runnable() {

         public void run() {

           // Bring window to foreground

           setVisible(true);

           toFront();

           // Convert stack dump to string

           StringWriter sw = new StringWriter();

           PrintWriter out = new PrintWriter(sw);

           t.printStackTrace(out);

           // Add string to end of text area

           textArea.append(sw.toString());

        }

     });

   }

  }

 


  

要測試這個處理,你需要一個程序來設置這個處理並拋出一些運行時異常。在下面的程序中,DumpTeat將會這樣做。為了簡單,DumpTest僅僅產生兩個異常。假如要拋出更多的異常,你可以自由的在程序裡添加更多的錯誤代碼。程序在第一個異常顯示後會暫停,你可以在異常間關閉異常堆棧窗口。

 

import java.io.*;

 

   public class DumpTest {

    public static void main(final String args[])

     throws Exception {

       Thread.UncaughtExceptionHandler handler =

         new StackWindow("Show Exception Stack", 400, 200);

       Thread.setDefaultUncaughtExceptionHandler(handler);

       new Thread() {

         public void run() {


  

           System.out.println(1 / 0);

         }

       }.start();

       BufferedReader br =

         new BufferedReader(new InputStreamReader(System.in));

       System.out.print("Press Enter for next exception");

       br.readLine();

       new Thread() {

         public void run() {

           System.out.println(args[0]);


  

         }

       }.start();

       System.out.print("Press Enter to end");

       br.readLine();

       System.exit(0);

     }

   }

 

編譯StackWindow和DumpTest。當你運行DumpTest時,在控制台裡會看見下面的內容:

> java DumpTest

   Press Enter for next exception

你將看見堆棧信息顯示在窗口裡的文本區域裡。


  

按下Enter,在控制台裡回看見下面的內容:

Press Enter to end

你可以在窗口的文本區裡看見另一個堆棧信息。

雖然你可以認為這些是處理未捕捉的異常的所有方法,其實還有更多的方法。模式對話框要求有它自己的事件線程,因為它自己非捕捉處理。系統屬性sun.awt.exception.handler覆蓋了所有容器,但不是好的文檔。RFE(增強型請求)提交了可擴展的屬性到正式的API中。

除Best Practices in Exception Handling外,2002年5月的技巧文章StackTraceElements也是一篇重要的參考。也可以看The Java Tutorial的Handling Errors Using Exception課程。


 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved