溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java中異常捕獲及處理的示例分析

發(fā)布時(shí)間:2021-09-01 13:38:22 來(lái)源:億速云 閱讀:82 作者:小新 欄目:開發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)java中異常捕獲及處理的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

一、Java異常簡(jiǎn)介

什么是異常?

程序運(yùn)行時(shí),發(fā)生的不被期望的事件,它阻止了程序按照程序員的預(yù)期正常執(zhí)行,這就是異常。異常發(fā)生時(shí),是任程序自生自滅,立刻退出終止。在Java中即,Java在編譯或運(yùn)行或者運(yùn)行過(guò)程中出現(xiàn)的錯(cuò)誤。

Java提供了更加優(yōu)秀的解決辦法:異常處理機(jī)制。

異常處理機(jī)制能讓程序在異常發(fā)生時(shí),按照代碼的預(yù)先設(shè)定的異常處理邏輯,針對(duì)性地處理異常,讓程序盡最大可能恢復(fù)正常并繼續(xù)執(zhí)行,且保持代碼的清晰。
Java中的異??梢允呛瘮?shù)中的語(yǔ)句執(zhí)行時(shí)引發(fā)的,也可以是程序員通過(guò)throw 語(yǔ)句手動(dòng)拋出的,只要在Java程序中產(chǎn)生了異常,就會(huì)用一個(gè)對(duì)應(yīng)類型的異常對(duì)象來(lái)封裝異常,JRE就會(huì)試圖尋找異常處理程序來(lái)處理異常。

Java異常機(jī)制用到的幾個(gè)關(guān)鍵字:try、catch、finally、throw、throws。

  •  try        -- 用于監(jiān)聽。將要被監(jiān)聽的代碼(可能拋出異常的代碼)放在try語(yǔ)句塊之內(nèi),當(dāng)try語(yǔ)句塊內(nèi)發(fā)生異常時(shí),異常就被拋出。

  • catch   -- 用于捕獲異常。catch用來(lái)捕獲try語(yǔ)句塊中發(fā)生的異常。

  • finally  -- finally語(yǔ)句塊總是會(huì)被執(zhí)行。它主要用于回收在try塊里打開的物力資源(如數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)連接和磁盤文件)。只有finally塊,執(zhí)行完成之后,才會(huì)回來(lái)執(zhí)行try或者catch塊中的return或者throw語(yǔ)句,如果finally中使用了return或者throw等終止方法的語(yǔ)句,則就不會(huì)跳回執(zhí)行,直接停止。

  • throw   -- 用于拋出異常。

  • throws -- 用在方法簽名中,用于聲明該方法可能拋出的異常。主方法上也可以使用throws拋出。如果在主方法上使用了throws拋出,就表示在主方法里面可以不用強(qiáng)制性進(jìn)行異常處理,如果出現(xiàn)了異常,就交給JVM進(jìn)行默認(rèn)處理,則此時(shí)會(huì)導(dǎo)致程序中斷執(zhí)行。

產(chǎn)生異常的原因:

  • 用戶輸入了非法數(shù)據(jù)。

  • 要打開的文件不存在。

  • 網(wǎng)絡(luò)通信時(shí)連接中斷,或者JVM內(nèi)存溢出。

這些異常有的是因?yàn)橛脩翦e(cuò)誤引起,有的是程序錯(cuò)誤引起的,還有其它一些是因?yàn)槲锢礤e(cuò)誤引起的。

三種類型的異常:

  • 檢查性異常:最具代表的檢查性異常是用戶錯(cuò)誤或問(wèn)題引起的異常,這是程序員無(wú)法預(yù)見的。例如要打開一個(gè)不存在文件時(shí),一個(gè)異常就發(fā)生了,這些異常在編譯時(shí)不能被簡(jiǎn)單地忽略。

  • 運(yùn)行時(shí)異常: 運(yùn)行時(shí)異常是可能被程序員避免的異常。與檢查性異常相反,運(yùn)行時(shí)異??梢栽诰幾g時(shí)被忽略。

  • 錯(cuò)誤: 錯(cuò)誤不是異常,而是脫離程序員控制的問(wèn)題。錯(cuò)誤在代碼中通常被忽略。例如,當(dāng)棧溢出時(shí),一個(gè)錯(cuò)誤就發(fā)生了,它們?cè)诰幾g也檢查不到的。

二、Java異常的分類

異常的根接口Throwable,其下有2個(gè)子接口,Error和Exception。

  • Error:指的是JVM錯(cuò)誤,這時(shí)的程序并沒(méi)有執(zhí)行,無(wú)法處理;

  • Exception:指的是程序運(yùn)行中產(chǎn)生的異常,用戶可以使用處理格式處理。

java中異常捕獲及處理的示例分析

Java 內(nèi)置異常類

Java 語(yǔ)言定義了一些異常類在 java.lang 標(biāo)準(zhǔn)包中。

標(biāo)準(zhǔn)運(yùn)行時(shí)異常類的子類是最常見的異常類。由于 java.lang 包是默認(rèn)加載到所有的 Java 程序的,所以大部分從運(yùn)行時(shí)異常類繼承而來(lái)的異常都可以直接使用。

Java 根據(jù)各個(gè)類庫(kù)也定義了一些其他的異常,下面的表中列出了 Java 的非檢查性異常。

異常描述
ArithmeticException當(dāng)出現(xiàn)異常的運(yùn)算條件時(shí),拋出此異常。例如,一個(gè)整數(shù)"除以零"時(shí),拋出此類的一個(gè)實(shí)例。
ArrayIndexOutOfBoundsException用非法索引訪問(wèn)數(shù)組時(shí)拋出的異常。如果索引為負(fù)或大于等于數(shù)組大小,則該索引為非法索引。
ArrayStoreException試圖將錯(cuò)誤類型的對(duì)象存儲(chǔ)到一個(gè)對(duì)象數(shù)組時(shí)拋出的異常。
ClassCastException當(dāng)試圖將對(duì)象強(qiáng)制轉(zhuǎn)換為不是實(shí)例的子類時(shí),拋出該異常。
IllegalArgumentException拋出的異常表明向方法傳遞了一個(gè)不合法或不正確的參數(shù)。
IllegalMonitorStateException拋出的異常表明某一線程已經(jīng)試圖等待對(duì)象的監(jiān)視器,或者試圖通知其他正在等待對(duì)象的監(jiān)視器而本身沒(méi)有指定監(jiān)視器的線程。
IllegalStateException在非法或不適當(dāng)?shù)臅r(shí)間調(diào)用方法時(shí)產(chǎn)生的信號(hào)。換句話說(shuō),即 Java 環(huán)境或 Java 應(yīng)用程序沒(méi)有處于請(qǐng)求操作所要求的適當(dāng)狀態(tài)下。
IllegalThreadStateException線程沒(méi)有處于請(qǐng)求操作所要求的適當(dāng)狀態(tài)時(shí)拋出的異常。
IndexOutOfBoundsException指示某排序索引(例如對(duì)數(shù)組、字符串或向量的排序)超出范圍時(shí)拋出。
NegativeArraySizeException如果應(yīng)用程序試圖創(chuàng)建大小為負(fù)的數(shù)組,則拋出該異常。
NullPointerException當(dāng)應(yīng)用程序試圖在需要對(duì)象的地方使用 null 時(shí),拋出該異常
NumberFormatException當(dāng)應(yīng)用程序試圖將字符串轉(zhuǎn)換成一種數(shù)值類型,但該字符串不能轉(zhuǎn)換為適當(dāng)格式時(shí),拋出該異常。
SecurityException由安全管理器拋出的異常,指示存在安全侵犯。
StringIndexOutOfBoundsException此異常由 String 方法拋出,指示索引或者為負(fù),或者超出字符串的大小。
UnsupportedOperationException當(dāng)不支持請(qǐng)求的操作時(shí),拋出該異常。

下面的表中列出了 Java 定義在 java.lang 包中的檢查性異常類。

異常描述
ClassNotFoundException應(yīng)用程序試圖加載類時(shí),找不到相應(yīng)的類,拋出該異常。
CloneNotSupportedException當(dāng)調(diào)用 Object 類中的 clone 方法克隆對(duì)象,但該對(duì)象的類無(wú)法實(shí)現(xiàn) Cloneable 接口時(shí),拋出該異常。
IllegalAccessException拒絕訪問(wèn)一個(gè)類的時(shí)候,拋出該異常。
InstantiationException當(dāng)試圖使用 Class 類中的 newInstance 方法創(chuàng)建一個(gè)類的實(shí)例,而指定的類對(duì)象因?yàn)槭且粋€(gè)接口或是一個(gè)抽象類而無(wú)法實(shí)例化時(shí),拋出該異常。
InterruptedException一個(gè)線程被另一個(gè)線程中斷,拋出該異常。
NoSuchFieldException請(qǐng)求的變量不存在
NoSuchMethodException請(qǐng)求的方法不存在

異常方法

下面的列表是 Throwable 類的主要方法:

序號(hào)方法及說(shuō)明
1public String getMessage()
返回關(guān)于發(fā)生的異常的詳細(xì)信息。這個(gè)消息在Throwable 類的構(gòu)造函數(shù)中初始化了。
2public Throwable getCause()
返回一個(gè)Throwable 對(duì)象代表異常原因。
3public String toString()
使用getMessage()的結(jié)果返回類的串級(jí)名字。
4public void printStackTrace()
打印toString()結(jié)果和棧層次到System.err,即錯(cuò)誤輸出流。
5public StackTraceElement [] getStackTrace()
返回一個(gè)包含堆棧層次的數(shù)組。下標(biāo)為0的元素代表?xiàng)m敚詈笠粋€(gè)元素代表方法調(diào)用堆棧的棧底。
6public Throwable fillInStackTrace()
用當(dāng)前的調(diào)用棧層次填充Throwable 對(duì)象棧層次,添加到棧層次任何先前信息中。

三、異常的使用及執(zhí)行流程

1、異常的處理方案

try...catch、try...catch...finally、try...finally
try{
可能會(huì)發(fā)生的異常
}catch(異常類型 異常名(變量)){
針對(duì)異常進(jìn)行處理的代碼
}catch(異常類型 異常名(變量)){
針對(duì)異常進(jìn)行處理的代碼
}...
[finally{
釋放資源代碼;
}]

注意:

  • catch 不能獨(dú)立于 try 存在。

  • catch里面不能沒(méi)有內(nèi)容

  • 在 try/catch 后面添加 finally 塊并非強(qiáng)制性要求的。

  • try 代碼后不能既沒(méi) catch 塊也沒(méi) finally 塊。

  • try里面越少越好。

  • try, catch, finally 塊之間不能添加任何代碼。

  • finally里面的代碼最終一定會(huì)執(zhí)行(除了JVM退出)

  • 如果程序可能存在多個(gè)異常,需要多個(gè)catch進(jìn)行捕獲。

  • 異常如果是同級(jí)關(guān)系,catch誰(shuí)前誰(shuí)后沒(méi)有關(guān)系
    如果異常之間存在上下級(jí)關(guān)系,上級(jí)需要放在后面

2、異常的執(zhí)行流程

java中異常捕獲及處理的示例分析

Error與Exception的區(qū)別:

Error(錯(cuò)誤)是系統(tǒng)中的錯(cuò)誤,程序員是不能改變的和處理的,是在程序編譯時(shí)出現(xiàn)的錯(cuò)誤,只能通過(guò)修改程序才能修正。一般是指與虛擬機(jī)相關(guān)的問(wèn)題,如系統(tǒng)崩潰,虛擬機(jī)錯(cuò)誤,內(nèi)存空間不足,方法調(diào)用棧溢等。對(duì)于這類錯(cuò)誤的導(dǎo)致的應(yīng)用程序中斷,僅靠程序本身無(wú)法恢復(fù)和和預(yù)防,遇到這樣的錯(cuò)誤,建議讓程序終止。

Exception(異常)表示程序可以處理的異常,可以捕獲且可能恢復(fù)。遇到這類異常,應(yīng)該盡可能處理異常,使程序恢復(fù)運(yùn)行,而不應(yīng)該隨意終止異常。

在catch捕獲異常時(shí),為什么不考慮使用Throwable類型,而只是使用Exception來(lái)進(jìn)行接收?

Throwable表示的范圍要比Exception大。實(shí)際上程序使用Throwable來(lái)進(jìn)行處理,沒(méi)有任何語(yǔ)法問(wèn)題,但是卻會(huì)存在邏輯問(wèn)題。因?yàn)榇藭r(shí)出現(xiàn)的(或者說(shuō)用戶能夠處理的)只有Exception類型,而如果使用Throwable接收,還會(huì)表示可以處理Error的錯(cuò)誤,而用戶是處理不了Error錯(cuò)誤的,所以在開發(fā)中用戶可以處理的異常都要求以Exception類為主。

異常是一起處理好還是分開處理好?

根據(jù)實(shí)際的開發(fā)要求是否嚴(yán)格來(lái)決定。在實(shí)際的項(xiàng)目開發(fā)項(xiàng)目工作中,所有的異常是統(tǒng)一使用Exception處理還是分開處理,完全根據(jù)開發(fā)者的項(xiàng)目開發(fā)標(biāo)準(zhǔn)來(lái)決定。如果項(xiàng)目開發(fā)環(huán)境嚴(yán)謹(jǐn),基本上要求針對(duì)每一種異常分別進(jìn)行處理,并且要詳細(xì)記錄下異常產(chǎn)生的時(shí)間以及產(chǎn)生的位置,這樣可以方便程序維護(hù)人員進(jìn)行代碼的維護(hù)。再次注意:處理多個(gè)異常時(shí),捕獲范圍小的異常要放在捕獲范圍大的異常之前處理。

throw和throws的區(qū)別?

throw和throws都是在異常處理中使用的關(guān)鍵字,區(qū)別如下:

  • throw:指的是在方法中人為拋出一個(gè)異常對(duì)象(這個(gè)異常對(duì)象可能是自己實(shí)例化或者拋出已存在的);

  • throws:在方法的聲明上使用,表示此方法在調(diào)用時(shí)必須處理異常。

檢查型異常(Checked Exception)與非檢查型異常(Unchecked Exception)區(qū)別?

  • 所有的檢查性異常都繼承自java.lang.Exception;所有的非檢查性異常都繼承自java.lang.RuntimeEx ception。

  • 檢查性異常和非檢查性異常最主要的區(qū)別在于其處理異常的方式:檢查性異常必須使用try catch或者throws等關(guān)鍵字進(jìn)行處理,否則編譯器會(huì)報(bào)錯(cuò);非檢查性異常一般是程序代碼寫的不夠嚴(yán)謹(jǐn)而導(dǎo)致的問(wèn)題,可以通過(guò)修改代碼來(lái)規(guī)避。

  • 常見的運(yùn)行時(shí)異常:空指針異常(NullPointerException)、除零異常(ArithmeticException)、數(shù)組越界異常(ArrayIndexOutOfBoundsException)等;

  • 常見的檢查性異常:輸入輸出異常(IOException)、文件不存在異常(FileNotFoundException)、SQL語(yǔ)句異常(SQLException)等。

assert關(guān)鍵字(了解)

在Java中,assert關(guān)鍵字是從JAVA SE 1.4 引入的,為了避免和老版本的Java代碼中使用了assert關(guān)鍵字導(dǎo)致錯(cuò)誤,Java在執(zhí)行的時(shí)候默認(rèn)是不啟動(dòng)斷言檢查的(這個(gè)時(shí)候,所有的斷言語(yǔ)句都 將忽略?。绻_啟斷言檢查,則需要用開關(guān)-enableassertions或-ea來(lái)開啟。

assert關(guān)鍵字語(yǔ)法很簡(jiǎn)單,有兩種用法:

  1. assert <boolean表達(dá)式>
    如果<boolean表達(dá)式>為true,則程序繼續(xù)執(zhí)行。
    如果為false,則程序拋出AssertionError,并終止執(zhí)行。

  2. assert <boolean表達(dá)式> : <錯(cuò)誤信息表達(dá)式>
    如果<boolean表達(dá)式>為true,則程序繼續(xù)執(zhí)行。
    如果為false,則程序拋出java.lang.AssertionError,并輸入<錯(cuò)誤信息表達(dá)式>。

例如:

public class Test {
	public static void main(String[] args) {
		int a = 10;
		int b = 2;
		assert a == 10:"a不等于10";
		System.out.println("a="+a);
	}
}

執(zhí)行結(jié)果為:

java中異常捕獲及處理的示例分析

public class Test {
	public static void main(String[] args) {
		int a = 10;
		int b = 2;
		assert a == 20:"a不等于20";
		System.out.println("a="+a);
	}
}

執(zhí)行結(jié)果為:

java中異常捕獲及處理的示例分析

四、自定義異常

在 Java 中你可以自定義異常。如果要自定義異常類,則擴(kuò)展Exception類即可,因此這樣的自定義異常都屬于檢查異常(checked exception)。如果要自定義非檢查異常,則擴(kuò)展自RuntimeException。

按照國(guó)際慣例,自定義的異常應(yīng)該總是包含如下的構(gòu)造函數(shù):

  • 一個(gè)無(wú)參構(gòu)造函數(shù)

  • 一個(gè)帶有String參數(shù)的構(gòu)造函數(shù),并傳遞給父類的構(gòu)造函數(shù)。

  • 一個(gè)帶有String參數(shù)和Throwable參數(shù),并都傳遞給父類構(gòu)造函數(shù)

  • 一個(gè)帶有Throwable 參數(shù)的構(gòu)造函數(shù),并傳遞給父類的構(gòu)造函數(shù)。

下面是IOException類的完整源代碼,可以借鑒。

package java.io;
 
public class IOException extends Exception {
    static final long serialVersionUID = 7818375828146090155L;
 
    public IOException() {
	super();
    }
 
    public IOException(String message) {
	super(message);
    }
 
    public IOException(String message, Throwable cause) {
        super(message, cause);
    }
 
    public IOException(Throwable cause) {
        super(cause);
    }
}

finally塊和return

  • 首先一個(gè)不容易理解的事實(shí):在 try塊中即便有return,break,continue等改變執(zhí)行流的語(yǔ)句,finally也會(huì)執(zhí)行。

  • finally中的return 會(huì)覆蓋 try 或者catch中的返回值。

  • finally中的return或異常會(huì)抑制(消滅)前面try或者catch塊中的異常。

感謝各位的閱讀!關(guān)于“java中異常捕獲及處理的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI