標籤:error 關鍵字 通過 虛擬 new 相關 客戶 pointer 多個
1.Java異常
在使用電腦語言進行項目開發的過程中,即使程式員把代碼寫得盡善盡美,在系統的運行過程中仍然會遇到一些問題,因為很多問題不是靠代碼能夠避免的,比如:客戶輸入資料的格式,輸入值的範圍,讀取檔案是否存在,網路是否始終保持通暢等等。
對於程式設計人員需要儘可能的預知所有可能發生的情況,儘可能的保證程式能在所有最糟糕的情況下都能運行。
但實際上,意外情況是不勝枚舉的,程式可能發生的異常情況遠遠多於程式員所能考慮到的意外情況。
Java的異常處理機制可以讓程式具有良好的容錯性,讓程式更加健壯,當程式出現異常時,系統會自動產生一個Exception對象來通知程式,從而實現將“業務功能實現代碼”和“錯誤處理代碼”分離,使程式具有更好的可讀性。
2.異常Exception
異常指的是在運行期出現的錯誤,在編譯階段出現的語法錯誤等,不能稱之為異常
Java程式在運行期所發生的例外狀況事件可分為兩類:Error Exception,不包含語法錯誤等這些錯誤,是Java中異常類的繼承關係圖:
Java虛擬機器無法解決的嚴重問題。如:JVM系統內部錯誤,系統崩潰,動態連結失敗等等,這種錯誤無法恢複或不可能捕獲,將導致應用程式中斷,通常程式無法處理這些錯誤,因此程式中不要試圖使用catch塊來捕獲Error對象。一般不進行處理。
其它因程式設計錯誤或偶然的外在因素導致的一般性問題,可以使用針對性的代碼進行處理。例如:算數異常,null 指標訪問,數組下標越界,所要讀取的檔案不存在等等
l 主要分成兩類:
l 一類是編譯異常,必須處理之後才能正常編譯(類找不到,IO異常...在API文檔中明確寫明throws...的方法,必須要進行處理)
l 一類是運行時異常RuntimeException,這種異常可以處理,也可以不處理(算數異常,null 指標等)
3.運行時異常
是指編譯器不要求強制處置的異常。一般是指程式設計時的邏輯錯誤,是程式員應該積極避免其出現的異常。java.lang.RuntimeException類及它的子類都是運行時異常。
對於這類異常,可以不作處理,因為這類異常很普遍,若全處理可能會對程式的可讀性和運行效率產生影響。
4.編譯異常
是指編譯器要求必須處置的異常。
Java程式必須捕獲或聲明所有編譯時間異常。
對於這類異常,如果程式不處理,可能會帶來意想不到的結果,編譯都不能通過
5.運行時異常的解決方案
對於這些運行時異常(不是編譯異常),一般有兩種解決方案:
- 一是遇到錯誤就終止程式的運行,即不對異常進行處理
- 二是由程式員在編寫程式時,就考慮到錯誤的檢測、錯誤訊息的提示,在拋給Java運行時環境的時候,就將這個異常對象捕獲,再進行處理(列印提示資訊等)
try嘗試:將可能發生異常的語句放入其中
catch捕獲:當try塊中的異常發生時,將產生一個異常對象,拿這個對象去匹配catch塊中的異常類,如果和catch中的類型匹配了,就執行這個catch塊中的語句,這也就意味著,catch塊可以有多個。
從以上程式可以看出,一個try後可以加多個catch塊,針對try語句塊中發生的異常分別捕獲,當然,只能有一個catch塊被執行,從執行的邏輯上看,和switch分支語句很相似。
如果把Exception類對應的異常catch塊放在前面的話,一旦發生錯誤,將直接進入該catch塊,因為所有的異常都是Exception或其子類的執行個體,而排在它後面的catch塊將永遠也不會得到執行的機會。
實際上,進行異常捕獲時,不僅應該把Exception類對應的catch塊放在最後,而且所有父類異常塊都應該排在子類異常catch塊的後面,簡記為:先處理小異常(子),後處理大異常(父)。否則編譯出錯
6.訪問異常資訊
如果程式需要在catch塊中訪問異常對象的相關資訊,可以通過訪問catch塊後的異常形參來獲得,當Java運行時決定調用某個catch塊來處理該異常對象時,會將異常對象賦值給catch塊後的異常參數(即:異常類型的形參),程式即可通過該參數來獲得異常的相關資訊。
所有的異常對象都包含了以下幾個常用的方法:
- getMessage():返回該異常的詳細描述資訊
- printStackTrace():將異常的跟蹤棧資訊列印出來
- printStackTrace(PrintStream s):將異常的跟蹤棧資訊輸出到指定的輸出資料流
- getStackTrace():返回該異常的跟蹤棧資訊
7.類型轉換異常:ClassCastException
import java.util.Date;
public class ErrorDemo {
public static void main(String[] args) {
Object obj = new Date();
String str = (String)obj;
}
}
8.null 指標異常:NullPointerExcetion
@Test
public void test5(){
String str = new String("AA");
str = null;
System.out.println(str.length());
}
9.編譯時間異常(必須捕獲)
在API中查看方法聲明後帶throws關鍵字的
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ErrorDemo {
public static void main(String[] args) {
FileInputStream in = null;
// in = new FileInputStream("a.txt");//error,沒有捕獲
try{
in = new FileInputStream("a.txt");//有可能會拋出異常,必須捕獲
}catch(FileNotFoundException fe){
fe.printStackTrace();
}
}
}
10.使用finally回收資源
有的時候,在try語句塊中開啟了一些實體資源,如資料庫連接,網路連接,磁碟檔案等,這些實體資源都必須顯式回收。
Java中的記憶體回收機制不會回收任何實體資源,記憶體回收機制只能回收記憶體中對象所佔用的記憶體資源。
那麼在哪裡回收實體資源呢?能在try語句塊中嗎?如果try塊中執行某條語句出現異常的話,則該語句之後的語句都沒有機會執行,這將導致其後的資源回收語句得不到執行。如果在catch塊中執行資源回收的話,catch語句塊也完全有可能得不到執行,這也會導致資源不能得到回收。
為了保證一定能夠回收在try塊中開啟的實體資源,異常處理處理機制提供了finally塊,不管try中的哪一條語句出現異常,也不管哪一個catch塊被執行,甚至在try或者catch中執行了return語句,finally塊總會被執行。完整的異常處理結構文法如下:
try{
業務處理語句
}catch(異常1 e1){
異常處理語句
}catch(異常2 e2){
異常處理語句
}
...
finally{
資源回收語句
}
11.注意:
在異常處理的結構中,只有try塊是必須的,也就是說,如果沒有try塊,則不能有後面的catch和finally塊,catch和finally兩者至少出現一個,當然也可以同時出現;捕獲子類異常的catch塊必須位於捕獲父類異常catch塊的前面;finally塊應該位於所有的catch塊後面
12.注意事項:
通常情況下,不要在finally塊中使用return或者thorw等導致方法終止的語句,(throw後面講),一旦在finally塊中使用了return或者throw語句,將會導致try塊,catch塊中的return,throw語句失效。
當程式在try/catch中遇到了return或者是throw語句,程式停止執行,但是並不會立即結束該方法,而是去尋找是否包含了finally塊,如果沒有finally塊,則立即執行return或者throw語句,方法終止;如果有finally塊,程式立即開始執行finally塊,只有當finally塊中語句執行完了,系統才會返回到try塊中執行return或者是throw語句;如果finally塊中也包含了return或者是throw等導致方法結束的語句,則在finally塊中已經終止了方法,程式就不會再跳回去執行try塊,catch塊中的任何代碼。換句話說,在finally中的return語句提前終止了方法。
13.提示:
盡量避免在finally塊中使用return,throw等語句,會導致一些非常特別,難以察覺的錯誤,不利於程式開發。
大資料JAVA基礎第十四天