異常處理,是非常非常非常非常重要的!尤其是實際投産的項目中,幾乎很難做到完全沒有錯誤(除非你的項目規模較小,或者測試團隊很牛X)。
說到這,貓哥講點題外話。貓哥曾經參與過一個項目,因為項目中用了幾個新人,當時貓哥也是新人之一。這個項目投産一段時間之後,發現會丢資料,就是本來應該是有1000筆業務發生吧,實際上可能系統隻記錄了998筆。第一次有使用者提出這個問題,我們就把各自的代碼review了一遍,麼有發現問題。大家都是新手,能實作就不錯了,而且程式員總感覺自己的代碼絕對OK,自我感覺良好。後來又丢了幾次資料,管項目的老大直覺:有事了!于是連夜召集項目組所有人員,我記得大概10幾個人。最後發現某新手未處理資料庫的一種異常,結果一大群人加了一晚上修改原始資料,修改完了怕有問題又想了N種方法驗證資料正确。當然,能補救回來真的是要謝天謝地了。
是以說,異常處理,真的很重要。現在從一個簡單的例子開始介紹之:
import java.util.Scanner;//導入用于擷取控制台輸入的類Scanner
public class ExceptionDemo {//異常示範的例子
public static void main(String[] args) {
while(true){
//使用無限循環模拟永遠線上等待指令的場景
Scanner sc = new Scanner(System.in);
System.out.println("大王,我們刑部這次要除掉哪個奸臣:");
String command = sc.nextLine();//模拟擷取大王指令
int army=100;//總兵力
int commandInt=Integer.parseInt(command);//了解大王旨意,刑部比較傻,隻能了解數字
int result=army/commandInt;
System.out.println("大王,搞定,我們除掉【"+commandInt+"】了!");//模拟響應使用者指令
}
}
}
好的,這個程式運作結果:
大王,我們刑部這次要除掉哪個奸臣:
1
大王,搞定,我們除掉【1】了!
大王,我們刑部這次要除掉哪個奸臣:
2
大王,搞定,我們除掉【2】了!
大王,我們刑部這次要除掉哪個奸臣:
可見效果非常良好,大王的指令在刑部可以立即得到執行,但是如果了解不了大王的意思呢(程式中運作到了解大王旨意的地方有錯誤)
比如這樣到輸入輸出:
大王,這次要除掉哪個奸臣:
0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ExceptionDemo.main(ExceptionDemo.java:12)
直接嗝屁了,大王下了一個指令0,其實大王的意思是這次不除人,然後刑部想去除掉【0】這個人,然後整個完蛋,大王哭了。
至于嘛!哪怕做不到,你得繼續把能做到的完成,然後做不到的給大王彙報下不就完了,直接嗝屁算幹嘛的
那怎麼辦呢,在比較古老的語言裡,大家可能會想到這樣:
import java.util.Scanner;//導入用于擷取控制台輸入的類Scanner
public class ExceptionDemo {//異常示範的例子
public static void main(String[] args) {
while(true){
//使用無限循環模拟永遠線上等待指令的場景
Scanner sc = new Scanner(System.in);
System.out.println("大王,我們刑部這次要除掉哪個奸臣:");
String command = sc.nextLine();//模拟擷取大王指令
int army=100;//總兵力
int commandInt=Integer.parseInt(command);//了解大王旨意,軍機處比較傻,隻能了解數字
if(commandInt==0)
{
System.out.println("大王,這個我們不行,該怎麼辦呢,這個家夥是:"+commandInt);
continue;
}
int result=army/commandInt;
System.out.println("大王,搞定,我們除掉【"+commandInt+"】了!");//模拟響應使用者指令
}
}
}
輸入輸出為:
大王,我們刑部這次要除掉哪個奸臣:
0
大王,這個我們不行,該怎麼辦呢,這個家夥是:0
大王,我們刑部這次要除掉哪個奸臣:
這樣的代碼,好像挺好的,沒問題。其實問題很大,首先就是太低級,你去算個除法也就算了,畢竟是你的任務,你遇到個除數是0,就得請大王幫你拿捏下,你這個也太低級了吧。Java作為一門牛X的進階語言,這樣處理問題,着實不妥。如果大王跟你說“張三”咋辦?
是以Java設計了try{}catch(){}finally{}的異常捕捉機制。try{}裡面放置可能産生錯誤的代碼,catch(){}小括号比對錯誤種類,{}處理異常,finally{}是不管有沒有錯誤發生,最後要跟大王彙報下。
OK,是以該問題可以如此處理。
import java.util.Scanner;//導入用于擷取控制台輸入的類Scanner
public class ExceptionDemo {//異常示範的例子
public static void main(String[] args) {
while(true){
//使用無限循環模拟永遠線上等待指令的場景
Scanner sc = new Scanner(System.in);
System.out.println("大王,我們刑部這次要除掉哪個奸臣:");
String command = sc.nextLine();//模拟擷取大王指令
int army=100;//總兵力
try{//可能有錯誤的語句放在try裡面
int commandInt=Integer.parseInt(command);//了解大王旨意,軍機處比較傻,隻能了解數字
int result=army/commandInt;
System.out.println("大王,搞定,我們除掉【"+commandInt+"】了!");//模拟響應使用者指令
}catch(Exception ex){
System.out.println("大王,我們遇到問題了:"+ex.getMessage());
}finally{
System.out.println("大王,之前"+command+"事情都過去了,您看還有需要什麼要訓示的嗎?");
}
}
}
}
大王,我們刑部這次要除掉哪個奸臣:
0
大王,我們遇到問題了:/ by zero
大王,之前0事情都過去了,您看還有需要什麼要訓示的嗎?
大王,我們刑部這次要除掉哪個奸臣:
1
大王,搞定,我們除掉【1】了!
大王,之前1事情都過去了,您看還有需要什麼要訓示的嗎?
大王,我們刑部這次要除掉哪個奸臣:
這樣一來,大王肯定對刑部的辦事态度滿意多了:
是以,Java異常機制的設計,十分符合一個有責任的人的辦事方式,永遠等待指令,不能執行的,請示決策者幫助,不管做沒做完,都要回報給決策者。OK,當然,好的決策者應該是具體問題具體分析,解決具體的困難,至于如何解決,且聽下回分解。