12.6 捕获所有异常
12.6.1 栈轨迹
java.lang.Throwable接口(java.lang.Excpetion实现了该接口)中的getStackTrace()方法返回栈轨迹的数组,我们来看一下它的使用。
1 import static java.lang.System.out; 2 public class WhoCalled { 3 static void f(){ 4 try { 5 throw new Exception(); 6 } 7 catch (Exception e) { 8 for(StackTraceElement ste : e.getStackTrace()) 9 out.println(ste.getClassName() + "." + ste.getMethodName() + "()@" + ste.getFileName() + ":" + ste.getLineNumber()); 10 } 11 } 12 static void g() {f();} 13 static void h() {g();} 14 public static void main(String args[]){ 15 f(); 16 out.println("---------------"); 17 g(); 18 out.println("---------------"); 19 h(); 20 } 21 }/* 22 WhoCalled.f()@WhoCalled.java:5 23 WhoCalled.main()@WhoCalled.java:15 24 --------------- 25 WhoCalled.f()@WhoCalled.java:5 26 WhoCalled.g()@WhoCalled.java:12 27 WhoCalled.main()@WhoCalled.java:17 28 --------------- 29 WhoCalled.f()@WhoCalled.java:5 30 WhoCalled.g()@WhoCalled.java:12 31 WhoCalled.h()@WhoCalled.java:13 32 WhoCalled.main()@WhoCalled.java:19 33 */
12.6.2 重新抛出异常
Exception的fillInStackTrace方法重新消除原来的栈轨迹,从该方法的调用点开始重新记录栈轨迹。一般配合Re-throw来使用。
1 import static java.lang.System.err; 2 public class ReThrow { 3 static void f() throws Exception{ 4 try { 5 throw new Exception(); 6 } 7 catch (Exception e) { 8 throw e; 9 } 10 } 11 static void g() throws Exception{ 12 try { 13 throw new Exception(); 14 } 15 catch (Exception e) { 16 throw (Exception)e.fillInStackTrace(); 17 } 18 } 19 public static void main(String args[]){ 20 try{ 21 f(); 22 } 23 catch(Exception e) { 24 e.printStackTrace(); 25 } 26 err.println("---------------"); 27 try{ 28 g(); 29 } 30 catch(Exception e) { 31 e.printStackTrace(); 32 } 33 } 34 }/*Output: 35 java.lang.Exception 36 at ReThrow.f(ReThrow.java:5) 37 at ReThrow.main(ReThrow.java:21) 38 --------------- 39 java.lang.Exception 40 at ReThrow.g(ReThrow.java:16) 41 at ReThrow.main(ReThrow.java:28) 42 */
12.6.3 异常链
1 class MyException extends Exception{ 2 MyException(String s){ 3 super(s); 4 } 5 } 6 public class Cause { 7 public static void main(String[] args) { 8 try { 9 try { 10 throw new Exception("Test"); 11 } 12 catch (Exception e) { 13 throw new MyException("Exception Without Original Cause"); 14 } 15 } 16 catch (MyException e) { 17 e.printStackTrace(); 18 } 19 try { 20 try { 21 throw new java.lang.NullPointerException(); 22 } 23 catch (Exception e) { 24 MyException mye = new MyException("Exception With Original Cause"); 25 mye.initCause(e); 26 throw mye; 27 } 28 } 29 catch (MyException e) { 30 e.printStackTrace(); 31 } 32 } 33 }/* 34 MyException: Exception Without Original Cause 35 at Cause.main(Cause.java:13) 36 MyException: Exception With Original Cause 37 at Cause.main(Cause.java:24) 38 Caused by: java.lang.NullPointerException 39 at Cause.main(Cause.java:21) 40 */
12.8 使用finally进行清理
1 import static java.lang.System.out; 2 import java.util.*; 3 public class Test { 4 public static void main(String args[]){ 5 Random r = new Random(); 6 int i = r.nextInt(3); 7 try{ 8 switch(i) { 9 case 0: 10 out.println("Case 0"); 11 break; 12 case 1: 13 out.println("Case 1"); 14 break; 15 case 2: 16 out.println("Case 2"); 17 return; 18 default: 19 out.println("Case Default"); 20 return; 21 } 22 } 23 finally { 24 out.println("Clean up"); 25 } 26 } 27 }/* 28 In output you will always see "Clean up" 29 */