您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java異常的處理方式有哪些”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Java異常的處理方式有哪些”文章能幫助大家解決問題。
異常在我們寫代碼是特別常見,因為程序員大部分時間都在修復bug,在java中通過throwable頂層類又可以分為兩個,一個是Error(錯誤),一個是Exception(異常)。
Error(錯誤) : Error與異常不同的是,錯誤并不能處理,而是程序員造成的問題,比如語法錯誤那就要程序員檢查自己的語法,比如結果錯誤(StackOverflowError和OutOfMemoryError
),那就要程序員檢查自己的邏輯。
Exception(異常) : 這個可以通過一些方式來處理,比如我們后面要講的throws(聲明異常),try{}catch{}(處理異常)這都是我們處理異常的方式,而異常又分為受查異常(編譯時異常)和非受查異常(運行時異常RuntimeException)。
編譯時異常:程序不能通過編譯,就是編譯時異常,比如:clone時必須要通過throws來聲明異常
運行時異常:指的是程序能通過編譯,但是運行時出現異常。比如:NullPointerException、
ArrayIndexOutOfBoundsException、ArithmeticException。
以上的異常我們都能進行處理解決,但是錯誤需要程序員自己檢查代碼。
我們有兩種方式來來進行處理:
一種是事前防御型:
boolean ret = false;
ret = 登陸游戲();
if (!ret) {
處理登陸游戲錯誤;
return;
} r
et = 開始匹配();
if (!ret) {
處理匹配錯誤;
return;
} r
et = 游戲確認();
if (!ret) {
處理游戲確認錯誤;
return;
} r
et = 選擇英雄();
if (!ret) {
處理選擇英雄錯誤;
return;
} r
et = 載入游戲畫面();
if (!ret) {
處理載入游戲錯誤;
return;
} .
.....
事前防御型就是每一步都要檢查是否出現了錯誤,這樣的缺點就是代碼顯得很混亂,效率低下;
一種是事后認錯型:
try {
登陸游戲();
開始匹配();
游戲確認();
選擇英雄();
載入游戲畫面();
...
} catch (登陸游戲異常) {
處理登陸游戲異常;
} catch (開始匹配異常) {
處理開始匹配異常;
} catch (游戲確認異常) {
處理游戲確認異常;
} catch (選擇英雄異常) {
處理選擇英雄異常;
} catch (載入游戲畫面異常) {
處理載入游戲畫面異常;
} .
....
這種做法就是將所有代碼可能出現的異常全部放在try里,如果發現異常在進行捕獲,這種就是先進行操作遇到問題在進行處理。
我們常常使用第二種trycatch這樣使代碼簡潔,清晰,效率更高。
如果哪段代碼不符合你的預期,這段代碼我們就要拋出異常,java中我們通過關鍵字throw來拋出異常。
語法是 throw new 異常(你要拋出的異常)
public class TestDemo { public static void func(int a) { if(a==10) { throw new RuntimeException("a==10不符合預期,拋出這個異常"); } } public static void main(String[] args) { func(10); } }
看這段代碼:比如我們10這個數字不符合我們程序的預期,所以要拋出異常,我們就可以這樣跑出: throw new RuntimeException("a==10不符合預期,拋出這個異常");
我們通常有兩種方式來處理異常,一種是通過throws聲明異常,一種是通過try{}catch{}通過try檢查代碼塊里是否有異常,如果有異常catch就進行捕獲,如果沒有異常就正常下面的代碼。
語法:throws 異常,異常,異常......(可聲明多個異常)
public class TestDemo { public static void function(int[] array) { System.out.println(array[100]); } public static void main(String[] args) { int[] array = {7, 8, 9, 5, 6}; function(array); } }
大家都知道這里訪問100下標是數組越界異常:
接下來通過throws來聲明異常:
還是會報錯。
當我們也給主函數聲明異常:
答案依然會報錯。
所以從這里我們得出了一個結論:通過throws只是告訴編譯器,這個方法可能會發生這個異常,只是聲明,但是并沒有進行處理異常。我們還可以發現,如果某一個方法出現了異常,那就會看這個方法有沒有處理異常,如果沒有處理就去看一看上層調用者有沒有處理異常。這里就是func只是聲明了異常,并沒有進行處理異常,然后去上層調用者有沒有處理異常(也就是main方法)還是沒有處理異常,最后就交給JVM來處理進行終止程序。聲明的異常必須是 Exception 或者 Exception 的子類。
那怎么進行處理異常呢?? 那就要通過我們接下來講解的try{}catch來進行處理異常。
try{
}catch(){
}
在Java我們利用try{}catch{}來處理異常;
語法:
try{ //可能發生異常的代碼 }catch(異常 變量){//例如:ArrayIndexOutOfBoundsException(要捕獲的異常) e(變量) //如果try中的代碼拋出異常了,此處catch捕獲時異常類型與try中拋出的異常類型一致時, //或者是try中拋出異常的基類時,就會被捕獲到 // 對異常就可以正常處理,處理完成后,跳出try-catch結構,繼續執行后序代碼 }finally{ //此處代碼一定會執行,用于資源清理掃尾等工作 }
我們先來講一下try{}catch(){}
/*在方法中處理異常*/ public class TestDemo { public static void function(int[] array) throws ArrayIndexOutOfBoundsException { try{ System.out.println(array[100]); }catch(ArrayIndexOutOfBoundsException e) { System.out.println("array[100]->數組下標越界異常catch->捕獲成功"); } } public static void main(String[] args) throws ArrayIndexOutOfBoundsException { int[] array = {7, 8, 9, 5, 6}; function(array); } } /*在main方法中處理異常*/ public class TestDemo { public static void function(int[] array) throws ArrayIndexOutOfBoundsException { System.out.println(array[100]); } public static void main(String[] args) throws ArrayIndexOutOfBoundsException { int[] array = {7, 8, 9, 5, 6}; try{ function(array); }catch(ArrayIndexOutOfBoundsException e) { System.out.println("array[100]->數組下標越界異常catch->捕獲成功"); } } }
我們使用try{}catch(){}就可以對異常進行處理,既可以在方法中處理異常也可以在main方法中處理異常,同時這里throws雖然沒有什么用處,但是可以清晰的告訴程序員,這個方法未來可能會發生這個異常,所以還是有必要的。
try{}catch{}注意點 一:
當捕獲異常成功的時候,后面的業務代碼正常執行,如果沒有捕獲那就不會執行。
try{}catch{}注意點 二:
當try里檢查到異常,catch就會捕獲,計算這個異常后面還有異常也不會執行。
try{}catch{}注意點三:
throws只是聲明異常,并沒有處理異常,我們要通過try{}catch(){}來處理異常。
try{}catch{}注意點四:
當catch捕獲的異常類型與發生異常類型不符合,就不會被捕獲,就繼續往外拋異常知道JVM收到后終止程序
try{}catch{}注意點五:
當發生多種異常的時候,那就要多種catch來捕獲,多種異常,多次捕獲。
try{}catch{}注意點六:
Exception是所有類的父類不能在前面捕獲,而是應該放在最末尾進行收尾工作。
既然Exception類是所對應異常類的父類,那可不可以捕獲Exception,即多次異常,一次捕獲呢??
catch 進行類型匹配的時候, 不光會匹配相同類型的異常對象, 也會捕捉目標異常類型的子類對象
答案是不建議的。因為當代碼進行復雜的時候,只捕獲Exception類并不知道究竟是什么處理出了問題。
打印異常信息
我們還可以利用printStackTrace來打印錯誤信息。
finally經常與try{}catch(){}進行一起使用,finally主要是進行資源的清理,的掃尾工作,且finally一定會被執行。
我們來看這樣一段代碼結果會是什么??
public class TestDemo { public static int function(int[] array) throws ArrayIndexOutOfBoundsException { try { System.out.println(array[100]); }catch(ArrayIndexOutOfBoundsException e) { System.out.println("array[100]->數組下標越界異常catch->捕獲成功"); return -1; }finally{ System.out.println("finally主要進行資源回收和清理的掃尾工作~~~"); return 9; } } public static void main(String[] args) throws ArrayIndexOutOfBoundsException,ArithmeticException { int[] array = {7, 8, 9, 5, 6}; System.out.println(function(array)); System.out.println("以下是業務代碼~~~~~~"); } }
答案并不是我們想的return-1,執行結束,而是return9,我們這里可以理解為finally的9將catch里的-1覆蓋。所以finally里面的代碼是一定會執行的。
我的理解:
第一步檢查try里面的代碼里是否有異常,如果有異常catch就進行捕獲,如果沒有異常接著往下執行,這里catch如果沒有捕獲到就看一看上層調用者有沒有處理,有處理就進行處理,沒有處理就交給JVM終止程序。如果catch捕獲到了,下面正常的業務代碼正常執行。最后無論catch是否捕獲到了異常,finally里面的代碼都會執行。
官方:
程序先執行 try 中的代碼
如果 try 中的代碼出現異常, 就會結束 try 中的代碼, 看和 catch 中的異常類型是否匹配.
如果找到匹配的異常類型, 就會執行 catch 中的代碼
如果沒有找到匹配的異常類型, 就會將異常向上傳遞到上層調用者.
無論是否找到匹配的異常類型, finally 中的代碼都會被執行到(在該方法結束之前執行).
如果上層調用者也沒有處理的了異常, 就繼續向上傳遞.
一直到 main 方法也沒有合適的代碼處理異常, 就會交給 JVM 來進行處理, 此時程序就會異常終止。
在我們做很大型的項目的時候,我們就會發現,我們遇到的異常,在Java中的內置異常并沒有,所以我們就需要自己定義一個異常,來維護我們實際中遇到的異常。
java 中雖然已經內置了豐富的異常類, 但是并不能完全表示實際開發中所遇到的一些異常,此時需要維護符合我們實際情況的異常結構
在Java中自己聲明異常,不是說你寫了個異常的名字就是一個異常,而是在你自己定義的異常需要取繼承原有的內置異常。
我們通過一個登陸的代碼來講解自定義異常:
class LogIn { private String name ="Admin";//用戶名 private String password= "CsDn1263987..0"; public void logInFor(String name,String password) throws UserNameErrorExecption, PasswordErrorException { if(!this.name.equals(name)){ throw new UserNameErrorExecption("用戶名參數異常!!!"); } if(!this.password.equals(password)) { throw new PasswordErrorException("用戶密碼參數異常!!!"); } System.out.println("~~~登陸成功~~~"); } } public class TestDemo{ public static void main(String[] args) throws UserNameErrorExecption, PasswordErrorException { LogIn logIn = new LogIn(); //logIn.logInFor("Admin","CsDn1263987..0"); try{ logIn.logInFor("Admin","CsDn126398..0"); }catch(UserNameErrorExecption nameError) { nameError.printStackTrace(); System.out.println("用戶名錯誤!!!"); }catch(PasswordErrorException passwordError) { passwordError.printStackTrace(); System.out.println("密碼錯誤!!!"); } } }
自定義異常:
class PasswordError extends Exception { public PasswordError(String message) { super(message); } }
class UserNameError extends Exception { public UserNameError(String message) { super(message); } }
這就是我們定義的兩個異常。
通過繼承Exception來定義兩個異常。
一般我們自定義異常要繼承Exception或者是RunTimeException,定義其他的也可以。
自定義異常通常會繼承自 Exception 或者 RuntimeException
繼承自 Exception 的異常默認是受查異常
繼承自 RuntimeException 的異常默認是非受查異常
關于“Java異常的處理方式有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。