欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javaSE中異常如何處理舉例詳解

 更新時間:2023年01月05日 08:53:52   作者:xyk:小白  
程序運行過程中發(fā)生了不正常的情況,這種不正常的情況叫做異常,下面這篇文章主要給大家介紹了關(guān)于javaSE中異常如何處理的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

一、異常的初識

1.1異常的概念

在Java中,將程序執(zhí)行過程中發(fā)生的不正常行為稱為異常。

在寫代碼時經(jīng)常遇到的:

1.算數(shù)異常
System.out.println(10 / 0);
 
// 執(zhí)行結(jié)果
Exception in thread "main" java.lang.ArithmeticException: / by zero
 
2.數(shù)組越界異常
int[] arr = {1, 2, 3};
System.out.println(arr[100]);
 
// 執(zhí)行結(jié)果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100
 
3.空指針異常
int[] arr = null;
System.out.println(arr.length);
 
// 執(zhí)行結(jié)果
Exception in thread "main" java.lang.NullPointerException

1.2異常的體系結(jié)構(gòu)

異常種類繁多,為了對不同異?;蛘咤e誤進行很好的分類管理,Java內(nèi)部維護了一個異常的體系結(jié)構(gòu):

從上圖中可以看到:

  • Throwable:是異常體系的頂層類,其派生出兩個重要的子類, Error 和 Exception
  • Error:指的是Java虛擬機無法解決的嚴重問題,比如:JVM的內(nèi)部錯誤、資源耗盡等,典型代表:StackOverflowError和OutOfMemoryError,一旦發(fā)生回力乏術(shù)。
  • Exception:異常產(chǎn)生后程序員可以通過代碼進行處理,使程序繼續(xù)執(zhí)行。比如:感冒、發(fā)燒。我們平時所說的異常就是Exception。

 1.3異常的分類

異常可能在編譯時發(fā)生,也可能在程序運行時發(fā)生,根據(jù)發(fā)生的時機不同,可以將異常分為:

1.編譯時異常
在程序編譯期間發(fā)生的異常,稱為編譯時異常,也稱為受檢查異常(Checked Exception)
 
public class Person {
private String name;
private String gender;
int age;
// 想要讓該類支持深拷貝,覆寫Object類的clone方法即可
@Override
public Person clone() {
return (Person)super.clone();
}
} 
編譯時報錯:
Error:(17, 35) java: 未報告的異常錯誤java.lang.CloneNotSupportedException; 必須對其進行捕獲或聲明以便拋出
 
2.運行時異常
 
在程序執(zhí)行期間發(fā)生的異常,稱為運行時異常,也稱為非受檢查異常(Unchecked Exception)
RunTimeException以及其子類對應(yīng)的異常,都稱為運行時異常。比如:NullPointerException、
ArrayIndexOutOfBoundsException、ArithmeticException。
 
注意:編譯時出現(xiàn)的語法性錯誤,不能稱之為異常。例如將 System.out.println 拼寫錯了, 寫成了
system.out.println. 此時編譯過程中就會出錯, 這是 "編譯期" 出錯。而運行時指的是程序已經(jīng)編譯通過得到class 文件了, 再由 JVM 執(zhí)行過程中出現(xiàn)的錯誤。

二、異常的處理和拋出

2.1防御式編程

錯誤在代碼中是客觀存在的. 因此我們要讓程序出現(xiàn)問題的時候及時通知程序猿. 主要的方式
1. LBYL: Look Before You Leap. 在操作之前就做充分的檢查. 即:事前防御型

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;
}
......
缺陷:正常流程和錯誤處理流程代碼混在一起, 代碼整體顯的比較混亂。

2. EAFP: It's Easier to Ask Forgiveness than Permission. "事后獲取原諒比事前獲取許可更容易". 也就是先操作, 遇到問題再處理. 即:事后認錯型

try {
登陸游戲();
開始匹配();
游戲確認();
選擇英雄();
載入游戲畫面();
...
} catch (登陸游戲異常) {
處理登陸游戲異常;
} catch (開始匹配異常) {
處理開始匹配異常;
} catch (游戲確認異常) {
處理游戲確認異常;
} catch (選擇英雄異常) {
處理選擇英雄異常;
} catch (載入游戲畫面異常) {
處理載入游戲畫面異常;
}
......
優(yōu)勢:正常流程和錯誤流程是分離開的, 程序員更關(guān)注正常流程,代碼更清晰,容易理解代碼

異常處理的核心思想就是 EAFP。
在Java中,異常處理主要的5個關(guān)鍵字:throw、try、catch、final、throws。

2.2異常的拋出

編寫程序時,如果程序中出現(xiàn)錯誤,此時就需要將錯誤的信息告知給調(diào)用者,比如:參數(shù)檢測。
在Java中,可以借助throw關(guān)鍵字,拋出一個指定的異常對象,將錯誤信息告知給調(diào)用者。具體語法如下:
throw new XXXException("異常產(chǎn)生的原因");

舉個例子:實現(xiàn)一個獲取數(shù)組中任意位置元素的方法。

public static int getElement(int[] array, int index){
if(null == array){
throw new NullPointerException("傳遞的數(shù)組為null");
} if(
index < 0 || index >= array.length){
throw new ArrayIndexOutOfBoundsException("傳遞的數(shù)組下標越界");
} r
eturn array[index];
}
public static void main(String[] args) {
int[] array = {1,2,3};
getElement(array, 3);
}

【注意事項】
1. throw必須寫在方法體內(nèi)部
2. 拋出的對象必須是Exception 或者 Exception 的子類對象
3. 如果拋出的是 RunTimeException 或者 RunTimeException 的子類,則可以不用處理,直接交給JVM來處理
4. 如果拋出的是編譯時異常,用戶必須處理,否則無法通過編譯
5. 異常一旦拋出,其后的代碼就不會執(zhí)行

2.3異常的捕獲

異常的捕獲,也就是異常的具體處理方式,主要有兩種:異常聲明throws 以及 try-catch捕獲處理。

異常聲明throws:

處在方法聲明時參數(shù)列表之后,當方法中拋出編譯時異常,用戶不想處理該異常,此時就可以借助throws將異常拋給方法的調(diào)用者來處理。即當前方法不處理異常,提醒方法的調(diào)用者處理異常。

語法格式:
修飾符 返回值類型 方法名(參數(shù)列表) throws 異常類型1,異常類型2...{

}

舉例:加載指定的配置文件config.ini

public class Config {
File file;
/*
FileNotFoundException : 編譯時異常,表明文件不存在
此處不處理,也沒有能力處理,應(yīng)該將錯誤信息報告給調(diào)用者,讓調(diào)用者檢查文件名字是否給錯誤了
*/
public void OpenConfig(String filename) throws FileNotFoundException{
if(filename.equals("config.ini")){
throw new FileNotFoundException("配置文件名字不對");
} /
/ 打開文件
}
public void readConfig(){
}
}

【注意事項】
1. throws必須跟在方法的參數(shù)列表之后
2. 聲明的異常必須是 Exception 或者 Exception 的子類
3. 方法內(nèi)部如果拋出了多個異常,throws之后必須跟多個異常類型,之間用逗號隔開,如果拋出多個異常類型具有父子關(guān)系,直接聲明父類即可。

4.調(diào)用聲明拋出異常的方法時,調(diào)用者必須對該異常進行處理,或者繼續(xù)使用throws拋出

try-catch捕獲并處理:

throws對異常并沒有真正處理,而是將異常報告給拋出異常方法的調(diào)用者,由調(diào)用者處理。如果真正要對異常進行處理,就需要try-catch。

語法格式:
try{
// 將可能出現(xiàn)異常的代碼放在這里
}catch(要捕獲的異常類型 e){
// 如果try中的代碼拋出異常了,此處catch捕獲時異常類型與try中拋出的異常類型一致時,或者是try中拋出異常的基類
時,就會被捕獲到
// 對異常就可以正常處理,處理完成后,跳出try-catch結(jié)構(gòu),繼續(xù)執(zhí)行后序代碼
}[catch(異常類型 e){
// 對異常進行處理
}finally{
// 此處代碼一定會被執(zhí)行到
}]
// 后序代碼
// 當異常被捕獲到時,異常就被處理了,這里的后序代碼一定會執(zhí)行
// 如果捕獲了,由于捕獲時類型不對,那就沒有捕獲到,這里的代碼就不會被執(zhí)行
注意:
1. []中表示可選項,可以添加,也可以不用添加
2. try中的代碼可能會拋出異常,也可能不會

【注意事項】
1. try塊內(nèi)拋出異常位置之后的代碼將不會被執(zhí)行
2. 如果拋出異常類型與catch時異常類型不匹配,即異常不會被成功捕獲,也就不會被處理,繼續(xù)往外拋,直到JVM收到后中斷程序----異常是按照類型來捕獲的

2.4異常的處理流程

關(guān)于 "調(diào)用棧"
方法之間是存在相互調(diào)用關(guān)系的, 這種調(diào)用關(guān)系我們可以用 "調(diào)用棧" 來描述. 在 JVM 中有一塊內(nèi)存空間稱為"虛擬機棧" 專門存儲方法之間的調(diào)用關(guān)系. 當代碼中出現(xiàn)異常的時候, 我們就可以使用 e.printStackTrace(); 的方式查看出現(xiàn)異常代碼的調(diào)用棧.

舉例:

public static void main(String[] args) {
try {
func();
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
} 
System.out.println("after try catch");
}
public static void func() {
int[] arr = {1, 2, 3};
System.out.println(arr[100]);
} 
// 直接結(jié)果
java.lang.ArrayIndexOutOfBoundsException: 100
at demo02.Test.func(Test.java:18)
at demo02.Test.main(Test.java:9)
after try catch

【異常處理流程總結(jié)】

  • 程序先執(zhí)行 try 中的代碼
  • 如果 try 中的代碼出現(xiàn)異常, 就會結(jié)束 try 中的代碼, 看和 catch 中的異常類型是否匹配.
  • 如果找到匹配的異常類型, 就會執(zhí)行 catch 中的代碼
  • 如果沒有找到匹配的異常類型, 就會將異常向上傳遞到上層調(diào)用者.
  • 無論是否找到匹配的異常類型, finally 中的代碼都會被執(zhí)行到(在該方法結(jié)束之前執(zhí)行).
  • 如果上層調(diào)用者也沒有處理的了異常, 就繼續(xù)向上傳遞.
  • 一直到 main 方法也沒有合適的代碼處理異常, 就會交給 JVM 來進行處理, 此時程序就會異常終止.

三、自定義異常類

3.1舉例:實現(xiàn)一個用戶登錄功能

public class LogIn {
 
private String userName = "admin";
private String password = "123456";
 
public static void loginInfo(String userName, String password) {
if (!userName.equals(userName)) {
} 
 
if(!password.equals(password)) {
} 
 
System.out.println("登陸成功");
 
}
 
public static void main(String[] args) {
loginInfo("admin", "123456");
}
}
 
具體方式:
1. 自定義異常類,然后繼承自Exception 或者 RunTimeException
2. 實現(xiàn)一個帶有String類型參數(shù)的構(gòu)造方法,參數(shù)含義:出現(xiàn)異常的原因
class UserNameException extends Exception {
public UserNameException(String message) {
super(message);
}
}
 
class PasswordException extends Exception {
public PasswordException(String message) {
super(message);
}
}

此時我們的 login 代碼可以改成:

public class LogIn {
 
private String userName = "admin";
private String password = "123456";
 
public static void loginInfo(String userName, String password)
throws UserNameException,PasswordException{
if (!userName.equals(userName)) {
throw new UserNameException("用戶名錯誤!");
} 
 
if(!password.equals(password)) {
throw new PasswordException("用戶名錯誤!");
} 
System.out.println("登陸成功");
}
 
public static void main(String[] args) {
try {
loginInfo("admin", "123456");
} catch (UserNameException e) {
e.printStackTrace();
} catch (PasswordException e) {
e.printStackTrace();
}
}
}

注意事項
自定義異常通常會繼承自 Exception 或者 RuntimeException
繼承自 Exception 的異常默認是受查異常
繼承自 RuntimeException 的異常默認是非受查異常

總結(jié) 

到此這篇關(guān)于javaSE中異常如何處理的文章就介紹到這了,更多相關(guān)javaSE異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • mybatis Plus 多表聯(lián)合查詢的實現(xiàn)示例

    mybatis Plus 多表聯(lián)合查詢的實現(xiàn)示例

    這篇文章主要介紹了mybatis Plus 多表聯(lián)合查詢的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 詳解SpringMVC的攔截器鏈實現(xiàn)及攔截器鏈配置

    詳解SpringMVC的攔截器鏈實現(xiàn)及攔截器鏈配置

    攔截器(Interceptor)是一種動態(tài)攔截方法調(diào)用的機制,在SpringMVC中動態(tài)攔截控制器方法的執(zhí)行。本文將詳細講講SpringMVC中攔截器參數(shù)及攔截器鏈配置,感興趣的可以嘗試一下
    2022-08-08
  • 詳解Spring簡單容器中的Bean基本加載過程

    詳解Spring簡單容器中的Bean基本加載過程

    本篇將對定義在 XMl 文件中的 bean,從靜態(tài)的的定義到變成可以使用的對象的過程,即 bean 的加載和獲取的過程進行一個整體的了解
    2017-05-05
  • Java Date類常用示例_動力節(jié)點Java學(xué)院整理

    Java Date類常用示例_動力節(jié)點Java學(xué)院整理

    在JDK1.0中,Date類是唯一的一個代表時間的類,但是由于Date類不便于實現(xiàn)國際化,所以從JDK1.1版本開始,推薦使用Calendar類進行時間和日期處理。這里簡單介紹一下Date類的使用,需要的朋友可以參考下
    2017-05-05
  • Java cglib動態(tài)代理原理分析

    Java cglib動態(tài)代理原理分析

    這篇文章主要介紹了Java cglib動態(tài)代理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-05-05
  • Java中的Thread.join()詳解

    Java中的Thread.join()詳解

    這篇文章主要介紹了Thread.join()詳解?,join是Thread類的一個方法,啟動線程后直接調(diào)用,本文通過實例代碼介紹了join方法的作用及用法詳解,需要的朋友可以參考下
    2023-09-09
  • Spring Cache使用RedisCache案例解析

    Spring Cache使用RedisCache案例解析

    這篇文章主要介紹了Spring Cache使用RedisCache案例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Java裁剪壓縮PNG圖片,透明背景色變黑的解決方案

    Java裁剪壓縮PNG圖片,透明背景色變黑的解決方案

    這篇文章主要介紹了Java裁剪壓縮PNG圖片,透明背景色變黑的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java讀取制表符文本轉(zhuǎn)換為JSON實現(xiàn)實例

    Java讀取制表符文本轉(zhuǎn)換為JSON實現(xiàn)實例

    在Java開發(fā)中,處理各種數(shù)據(jù)格式是常見的任務(wù),本文將介紹如何使用Java讀取制表符文本文件,并將其轉(zhuǎn)換為JSON格式,以便于后續(xù)的數(shù)據(jù)處理和分析,我們將使用Java中的相關(guān)庫來實現(xiàn)這個過程,并提供詳細的代碼示例
    2024-01-01
  • Mybatis數(shù)據(jù)批量插入如何實現(xiàn)

    Mybatis數(shù)據(jù)批量插入如何實現(xiàn)

    這篇文章主要介紹了Mybatis數(shù)據(jù)批量插入如何實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07

最新評論