揭短ExceptionUtils:有些異常並沒有root cause的,此時,調用ExceptionUtils的getRootCause(final Throwable throwable)返回值是null,而你調用其getRootCauseMessage(final Throwable th)時,... ...
先如下代碼:
1 @Test 2 public void testException1() { 3 System.out.println("begin..."); 4 int[] arr = new int[]{1}; 5 System.out.println(arr[1]); 6 }
執行結果:
java.lang.ArrayIndexOutOfBoundsException: 1 at com.emax.paycenter.web.controller.PayCenterAgentPayAPITest.testException1(PayCenterAgentPayAPITest.java:5)
異常是從第5行拋出來的,控制台里顯示的異常堆棧信息也是始於第5行。
我們在寫程式時往往要捕獲異常。如下是畫蛇添足型:
1 @Test 2 public void testException() { 3 try { 4 System.out.println("begin..."); 5 int[] arr = new int[]{1}; 6 System.out.println(arr[1]); 7 } catch (Exception ex) { 8 throw ex; 9 } 10 }
很明顯,捕獲了異常,卻只是throw出去,沒任何意義!
如下處理方式也不可取:
1 @Test 2 public void testException() { 3 try { 4 System.out.println("begin..."); 5 int[] arr = new int[]{1}; 6 System.out.println(arr[1]); 7 } catch (Exception ex) { 8 throw new MyException( ex.getMessage() ); 9 } 10 }
異常的堆棧始於拋出異常的代碼行。catch里經過這樣中轉後,導致堆棧信息的顯示的行號不再是6,而是8。尤其當代碼邏輯複雜時,這樣做無意增加了排障的難度。
當然,我們有時要在系統里通過自定義異常類型,實現我們所需的邏輯控制(自定義異常是個好東西哦)。如果真要通過MyExecption中轉出去,可在throw之前將完整的異常信息記錄到日誌文件里。
類似如下代碼是不是很熟悉?
1 public int myBiz() { 2 int result; 3 try { 4 System.out.println("begin..."); 5 int[] arr = new int[]{1}; 6 result = arr[1]; 7 return result; 8 } catch (Exception e) { 9 return 0; 10 } 11 }
私自吞異常是要犯法的哦~~
哈哈,去翻翻自己寫的代碼吧~
ExceptionUtils記錄異常
.net程式員都知道,記錄一個異常信息時,直接ex.ToString()就可以了。
如果在java里,你還這樣,那就out了。查看一下Exception的基類——Throwable的toString()方法,可知,ex.ToString()返回的是異常類型和message。
這時,要列印完整的日誌信息,apache commons-lang3包里的ExceptionUtils可要派上用場了。 沒錯,用ExceptionUtils.getStackTrace(final Throwable throwable)
揭短ExceptionUtils
有些異常並沒有root cause的,此時,調用ExceptionUtils的getRootCause(final Throwable throwable)返回值是null,而你調用其getRootCauseMessage(final Throwable th)時,反而有返回值。 查看getRootCauseMessage的代碼實現,發現它做了二元判斷,如果root cause是null,它就去取th本身的message。 前者返回null,後者有返回值,自我趕腳有些費解!whataboutu?
//public class ExceptionUtils { public static Throwable getRootCause(final Throwable throwable) { final List<Throwable> list = getThrowableList(throwable); return list.size() < 2 ? null : (Throwable)list.get(list.size() - 1); } public static String getRootCauseMessage(final Throwable th) { Throwable root = ExceptionUtils.getRootCause(th); root = root == null ? th : root; return getMessage(root); }