java 异常与记录日志
一. 你可能还想利用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 *///:~