闲来无事,看看JUnit的源代码。刚刚开始看就发现一段有趣的代码:
public String trace() { StringWriter stringWriter = new StringWriter(); PrintWriter writer = new PrintWriter(stringWriter); thrownException().printStackTrace(writer); StringBuffer buffer = stringWriter.getBuffer(); return buffer.toString(); }
此前我并未接触过StringWriter和PrintWriter。对此感到好奇。其实Java的IO是比较复杂的,因为很多类提供的接口需要的IO参数类型是固定的,而我们掌握的数据或者说需要输入的数据却是很多封装类型的,故此经常需要做封装工作。(个人的小体会而已,我对IO一块没有太多经验)
查阅Java API文档,发现了:
void printStackTrace() Prints this throwable and its backtrace to the standard error stream. void printStackTrace(PrintStream s) Prints this throwable and its backtrace to the specified print stream. void printStackTrace(PrintWriter s) Prints this throwable and its backtrace to the specified print writer.
从上面的信息可以看出,Throwable(Exception继承的一个基类)的错误输入有三种,printStackTrace()是指将异常本身和异常信息输出到标准的错误流;printStatckTrace(PrintStream s)是指将异常本身和异常信息输出到PrintStream的对象中;第三种则是输出到PrintWriter中。
在普通的情况中,如果我们用IDE的话,错误一般是直接输出到Console中,但是有时候我们需要将异常信息输出到文件中、或者是其他网页中,这时候就需要使用带参数的两个API接口。
此处使用PrintWriter,PrintWriter的构造函数比较多种,我使用StringWriter作为构造参数。
为了证实可行性。写一个小程序跑一下。
import java.io.PrintWriter; import java.io.StringWriter; @SuppressWarnings("serial") public class MyException extends Exception{ public String getPrintStackTraceAsString(){ StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); printStackTrace(pw);//将异常信息输入到pw(PrintWriter)中 StringBuffer sb = sw.getBuffer(); return sb.toString(); } }
public class TestException { public static void main(String[] args) { try { throw new MyException(); } catch (MyException e) { // 由于实现的方法定义在MyException中,所以catch的参数不可以向上转型为Exception System.out.println("I am not an average Exception: " + e.getPrintStackTraceAsString()); // e.printStackTrace(); } } }
当使用e.printStackTrace()方法时,得到以下结果:
MyException
at TestException.main(TestException.java:4)
而使用我们定义的方法时:
I am not an average Exception: MyException
at TestException.main(TestException.java:4)
相关代码:https://github.com/louiscai/StringWriterWithPrintWriter
======================正文结束==================
此外:
1)Throwable本身也有getStackTrace()方法。
2)关于PrintWriter和PrintStream的区别,可以参考:http://hi.baidu.com/shdren09/item/8b1d2631e78b7abf623aff3f