一. 你可能還想利用java.util.logging工具將輸出記錄到日志中
package exceptions; //: exceptions/LoggingExceptions.java // An exception that reports through a Logger. import java.util.logging.*; import java.io.*; class LoggingException extends Exception { private static Logger logger = Logger.getLogger("LoggingException");//Logger.getLogger()方法創建了一個String參數相關聯的Logger對象 //(通常是與錯誤相關的包名或類名),這個Logger對象會將其輸出發送到System.err public LoggingException() { StringWriter trace = new StringWriter(); printStackTrace(new PrintWriter(trace));//printStackTrace不會產生默認字符串,為了獲取字符串,我們使用重載的 //printStackTrace()方法,它接受一個java.io.PrintWriter()對象作為參數,如果我們將一個SrtingWriter對象傳遞給 //這個Printwrite()構造器,那么就可以調用toString()方法,就可以抽取為一個String logger.severe(trace.toString());//severe寫入日志 } } public class LoggingExceptions { public static void main(String[] args) { try { throw new LoggingException(); } catch(LoggingException e) { System.err.println("Caught " + e); } try { throw new LoggingException(); } catch(LoggingException e) { System.err.println("Caught " + e); } } } /* Output: (85% match) Aug 30, 2005 4:02:31 PM LoggingException <init> SEVERE: LoggingException at LoggingExceptions.main(LoggingExceptions.java:19) Caught LoggingException Aug 30, 2005 4:02:31 PM LoggingException <init> SEVERE: LoggingException at LoggingExceptions.main(LoggingExceptions.java:24) Caught LoggingException *///:~
二. 盡管LoggingException將所有記錄日志的基礎設施都構建在了異常自身中,使用它非常方便.但更常見的是我們需要捕獲和記錄其它人編寫的異常,
package exceptions; //: exceptions/LoggingExceptions2.java // Logging caught exceptions. import java.util.logging.*; import java.io.*; public class LoggingExceptions2 { private static Logger logger = Logger.getLogger("LoggingExceptions2"); static void logException(Exception e) { StringWriter trace = new StringWriter(); e.printStackTrace(new PrintWriter(trace)); logger.severe(trace.toString()); } public static void main(String[] args) { try { throw new NullPointerException(); } catch(NullPointerException e) { logException(e); } } } /* Output: (90% match) Aug 30, 2005 4:07:54 PM LoggingExceptions2 logException SEVERE: java.lang.NullPointerException at LoggingExceptions2.main(LoggingExceptions2.java:16) *///:~
我們還可以進一步自定義異常,比如加入額外的構造器和成員,因為我們必須在異常處理信息中生成日志信息,新的異常添加了字段x以及設定x值的構造器和讀取數據,的方法,此外,還覆蓋了getMassge()方法,以產生更詳細的信息,對異常來說getMassge()方法有點類似於toString()方法
package exceptions; //: exceptions/ExtraFeatures.java // Further embellishment of exception classes. import static net.mindview.util.Print.*; class MyException2 extends Exception { private int x; public MyException2() {} public MyException2(String msg) { super(msg); } public MyException2(String msg, int x) { super(msg); this.x = x; } public int val() { return x; } public String getMessage() { //相當於toString()方法 return "Detail Message: "+ x + " "+ super.getMessage(); } } public class ExtraFeatures { public static void f() throws MyException2 { print("Throwing MyException2 from f()"); throw new MyException2(); } public static void g() throws MyException2 { print("Throwing MyException2 from g()"); throw new MyException2("Originated in g()"); } public static void h() throws MyException2 { print("Throwing MyException2 from h()"); throw new MyException2("Originated in h()", 47); } public static void main(String[] args) { try { f(); } catch(MyException2 e) { e.printStackTrace(System.out); } try { g(); } catch(MyException2 e) { e.printStackTrace(System.out); } try { h(); } catch(MyException2 e) { e.printStackTrace(System.out); System.out.println("e.val() = " + e.val()); } } } /* Output: Throwing MyException2 from f() MyException2: Detail Message: 0 null at ExtraFeatures.f(ExtraFeatures.java:22) at ExtraFeatures.main(ExtraFeatures.java:34) Throwing MyException2 from g() MyException2: Detail Message: 0 Originated in g() at ExtraFeatures.g(ExtraFeatures.java:26) at ExtraFeatures.main(ExtraFeatures.java:39) Throwing MyException2 from h() MyException2: Detail Message: 47 Originated in h() at ExtraFeatures.h(ExtraFeatures.java:30) at ExtraFeatures.main(ExtraFeatures.java:44) e.val() = 47 *///:~