【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 的 |

Java 學習之路





Albert
07/03其實學過 Java 的你一定知道,那些編譯器不強制檢查的 Exception 叫 Checked Exception ...
多打了一個"不"字