異常只為異常服務,這是何解?難道異常還能為其他服務不成?確實能,異常原本是正常邏輯的一個補充,但是有時候會被當作主邏輯使用,看如下代碼:
//判斷一個枚舉是否包含String枚舉項
public static<T extends Enum<T>>boolean Contain(Class<T>c, String name){
boolean result=false;
try{
Enum.valueOf(c, name);
result=true;
}catch(RuntimeException e){
//只要是拋出異常,則認為是不包含
}
return result;
}
判斷一個枚舉是否包含指定的枚舉項,這裡會根據valueOf方法是否拋出異常來進行判斷,如果拋出異常(一般是IllegalArgumentException異常),則認為是不包含,若不拋出異常則可以認為包含該枚舉項,看上去這段代碼很正常,但是其中卻有三個錯誤:
異常判斷降低了系統性能。
降低了代碼的可讀性,只有詳細瞭解valueOf方法的人才能讀懂這樣的代碼,因為valueOf拋出的是一個非受檢異常。
隱藏了運行期可能產生的錯誤,catch到異常,但沒有做任何處理。
我們這段代碼是用一段異常實現了一個正常的業務邏輯,這導致代碼產生了壞味道。要解決此問題也很容易,即不在主邏輯中使用異常,代碼如下:
//判斷一個枚舉是否包含String枚舉項
public static<T extends Enum<T>>boolean Contain(Class<T>c, String name){
//遍歷枚舉項
for(T t:c.getEnumConstants()){
//枚舉項名稱是否相等
if(t.name().equals(name)){
return true;
}
}
return false;
}
異常只能用在非正常的情況下,不能成為正常情況的主邏輯,也就是說,異常只是主場景中的輔助場景,不能喧賓奪主。
而且,異常雖然是描述例外事件的,但能避免則避免之,除非是確實無法避免的異常,例如:
public static void main(Stringargs){
File file=new File("文件.txt");
try{
FileInputStream fis=new FileInputStream(file);
/*其他業務邏輯處理*/
}catch(FileNotFoundException e){
//異常處理
}
}
這樣一段代碼經常會在我們的項目中出現,但經常寫並不代表不可優化,這裡的異常類FileNotFoundException完全可以在它誕生前就消除掉:先判斷文件是否存在,然後再生成FileInputStream對象,代碼如下:
public static void main(Stringargs){
File file=new File("文件.txt");
//經常出現的異常情況,可以先做判斷
if(fle.exists()&&!fle.isDirectory()){
try{
}catch(){
}
}
}
雖然增加了if判斷語句,增加了代碼量,但是卻會減少FileNotFoundException異常出現的幾率,提高了程序的性能和穩定性。
注意 異常只為確實異常的事件服務。