【Guava 教學】(5)程式 90% 比率在管理與處理錯誤
【Guava 教學】(4)實作 toString、equals 與 hashCode 的幫手 << 前情 這篇是要來談談 Guava 的 Throwables,不過正如標題寫的,程式 90% 的比率在管理與處理錯誤,既然如此,那我們還是從頭來認識一些錯誤處理的基礎好了。 假設你有個提款方法原先是這麼寫的: public boolean withdraw(int money) { if(money >= 0 && this.balance >= money) { this.balance -= money; return true; } retrun false; }
public void withdraw(int money) throws Throwable { if(money < 0 || this.balance < money) { throw new Throwable("提款失敗"); } this.balance -= money; } 可以搭配 不過,參數 public void withdraw(int money) throws Exception { if(money < 0) throw new IllegalArgumentException("提款額不能傳入負數"); if(this.balance < money) { throw new Exception("餘額不足"); } this.balance -= money; } Java 為 前面講過,編譯器會強制客戶端要處理例外,除了那些 其實學過 Java 的你一定知道,那些編譯器強制檢查的 程式中可能會捕捉例外,對例外做些能做的處理,再重新拋出例外,像是 要抓還是要丟? 中提到的,因此,像這樣的程式碼倒蠻常見的: public void doSomething() throws IOException, SQLException { try { someMethodThatCouldThrowAnything(); } catch(IKnowWhatToDoWithThisException e) { handle(e); } catch(SQLException e) { log(e); throw e; } catch(IOException e) { log(e); throw e; } catch(Throwable t) { log(t); throw new RuntimeException(t); } } 最後一個 public void doSomething() throws IOException, SQLException { try { someMethodThatCouldThrowAnything(); } catch(IKnowWhatToDoWithThisException e) { handle(e); } catch(SQLException | IOException e) { // JDK7 multi-catch 語法 log(e); throw e; } catch(Throwable t) { log(t); throw new RuntimeException(t); } } 那麼如果是 JDK6 呢?可以使用 Guava 的 public void doSomething() throws IOException, SQLException { try { someMethodThatCouldThrowAnything(); } catch(IKnowWhatToDoWithThisException e) { handle(e); } catch(Throwable t) { log(t); Throwables.propagateIfInstanceOf(t, IOException.class); Throwables.propagateIfInstanceOf(t, SQLException.class); throw Throwables.propagate(t); } }
... public static <X extends Throwable> void propagateIfInstanceOf( @Nullable Throwable throwable, Class<X> declaredType) throws X { if (throwable != null && declaredType.isInstance(throwable)) { throw declaredType.cast(throwable); } } ... 而 ... public static RuntimeException propagate(Throwable throwable) { propagateIfPossible(checkNotNull(throwable)); throw new RuntimeException(throwable); } ... Guava 的 我這邊想再多談一下 JDK7 的 multi-catch,在 multi-catch 時, ... } catch(IOException e) { handle(e); } catch(FileNotFoundException e) { handle(e); } ... 只是為什麼 ... } catch(FileNotFoundException e) { handle(e); } catch(IOException e) { handle(e); } ... 好像合理耶!其實是因為,還沒使用 multi-catch 前的寫法本來就沒必要,想想你在 ... } catch(IOException e) { handle(e); } ... 你知道,Java 的編譯器蠻雞婆的,因此在 ... } catch(IOException | SQLException e) { if(e instanceof FileNotFoundException) { doSomethingWhenFileNotFoundException(e); } handle(e); } ... 這完全是不建議,multi-catch 本來就是讓你可以整理相同的例外處理程式碼,如果你用了 ... } catch(FileNotFoundException e) { doSomethingWhenFileNotFoundException(e); } catch(IOException e) { handle(e); } catch(SQLException e) { handle(e); } ... 那麼用 multi-catch 整理後,應該要是這樣才對: ... } catch(FileNotFoundException e) { doSomethingWhenFileNotFoundException(e); } catch(IOException | SQLException e) { handle(e); } ... 這邊想表達的是,語法的簡便,其實只是讓你省去少打幾個字之類的麻煩,不過如果你不知道本質上該如何處理,那麼也是會發生濫用的情況。同樣地,Guava 的 |
Albert
07/03
其實學過 Java 的你一定知道,那些編譯器不強制檢查的 Exception 叫 Checked Exception ...
多打了一個"不"字