java经常会出现异常的是,“Java异常Exception”总结
1. 異常(Exception)。 2.Java中的異常分為兩大類(lèi): a) Checked exception? (非? Runtime Exception) 非運(yùn)行時(shí)異常 b) Unchecked exception(Runtime Exception) 運(yùn)行時(shí)異常 3. Java中所有的異常類(lèi)都會(huì)直接或間接地繼承自Exception。 4. RuntimeException類(lèi)也是直接繼承自Exception類(lèi),它叫做運(yùn)行時(shí)異常,Java中所有 的運(yùn)行時(shí)異常都會(huì)直接或間接地繼承自RuntimeException。 5. Java 中凡是繼承自Exception而不是繼承自RuntimeException的類(lèi)都是非運(yùn)行時(shí)異 常。 如附件圖:運(yùn)行—非運(yùn)行異常區(qū)分.jpg 6.異常處理的一般結(jié)構(gòu)是: try { } catch(Exception e) { } finally { } 無(wú)論程序是否出現(xiàn)異常,finally 塊中的代碼都是會(huì)被執(zhí)行的。 7. 對(duì)于非運(yùn)行時(shí)異常(checked? exception),必須要對(duì)其進(jìn)行處理,處理方式有兩種: 第一種是使用try.. catch…finally 進(jìn)行捕獲;第二種是在調(diào)用該會(huì)產(chǎn)生異常的方法所在 的方法聲明throwsException 繼續(xù)往外拋。 8. 對(duì)于運(yùn)行時(shí)異常(runtime? exception),我們可以不對(duì)其進(jìn)行處理,也可以對(duì)其進(jìn)行處理。推薦不對(duì)其進(jìn)行處理。 9. NullPointerException是空指針異常,出現(xiàn)該異常的原因在于某個(gè)引用為null,但你卻調(diào)用了它的某個(gè)方法。這時(shí)就會(huì)出現(xiàn)該異常。 10.Error和Exception之間關(guān)系:程序可能會(huì)發(fā)生錯(cuò)誤Error,可能會(huì)出現(xiàn)異常Exception。異常是我們可以處理的情況,但是如果程序發(fā)生了錯(cuò)誤,我們就不能處理了。錯(cuò)誤的危險(xiǎn)級(jí)別比異常更高。一般情況下如果我們?cè)诖a上不做任何處理的話,程序發(fā)生了異常,那么異常代碼后面的代碼就不會(huì)再去執(zhí)行了,但是如果我們對(duì)異常代碼提前做了相應(yīng)的處理(比如拋出或捕獲),那么當(dāng)異常發(fā)生的時(shí)候,代碼還是能夠繼續(xù)往下執(zhí)行的;而對(duì)于錯(cuò)誤Error,我們無(wú)能為力,沒(méi)有辦法做任何處理,也沒(méi)有任何辦法讓錯(cuò)誤代碼下面的代碼繼續(xù)執(zhí)行。 系統(tǒng)對(duì)于運(yùn)行時(shí)異常和非運(yùn)行時(shí)異常的處理方式是完全不一樣的。 Java里面每一個(gè)異常都是一個(gè)類(lèi),當(dāng)程序執(zhí)行到某一行如果出現(xiàn)異常的話,它會(huì)在可能產(chǎn)生異常的這一行代碼的位置處產(chǎn)生一個(gè)針對(duì)于這個(gè)異常的一個(gè)異常對(duì)象(至于是哪個(gè)異常類(lèi)型的對(duì)象,它會(huì)根據(jù)實(shí)際的異常情況自己去選擇),這個(gè)對(duì)象是由它運(yùn)行的時(shí)候來(lái)去動(dòng)態(tài)的去生成的。如下代碼: Int c = 0; Try { Int a = 3; Int b = 0; C = a / b; } catch (ArithmeticException e) { e.printStrackTrace(); } 如果出現(xiàn)異常,會(huì)生成一個(gè)異常類(lèi)對(duì)象,這個(gè)對(duì)象直接賦給引用變量e。 注意:在try塊里面,如果某行代碼出現(xiàn)異常了,那么流程會(huì)直接從這行代碼轉(zhuǎn)到catch塊里面,try塊里面此行代碼后面的代碼不會(huì)再去執(zhí)行了。Catch塊完了之后再往后正常去執(zhí)行catch塊后面的代碼。 可能發(fā)生異常的代碼放到try里面。一定要執(zhí)行的代碼放到finally里面。 程序光有try和finally,沒(méi)有catch也是可以的。也是可以正常編譯通過(guò)的。這樣就相當(dāng)于沒(méi)有對(duì)異常進(jìn)行處理,和不加try、catch是一個(gè)效果,后面的代碼不會(huì)再去執(zhí)行。 一個(gè)try后面不論跟著多少個(gè)catch,最多只會(huì)有一個(gè)catch被執(zhí)行。 在一個(gè)方法里面我們可以自己手工的去拋出異常,用關(guān)鍵字throw,拋出的是異常對(duì)象(異常出現(xiàn)的時(shí)候產(chǎn)生的也是異常對(duì)象)。如下代碼作解釋: 所有的異常實(shí)際上都是對(duì)象。 異常的第一種方式是try? catch捕獲,第二種方式是拋出異常,拋出異常是由調(diào)用這個(gè)方法的那個(gè)方法對(duì)這個(gè)異常進(jìn)行處理,它的處理方式也是有兩種,要么捕獲,要么繼續(xù)拋出,繼續(xù)拋給調(diào)用它的方法,就這樣一層一層的網(wǎng)上拋。最后,main方法是我們的最后一個(gè)方法,如果main方法我們也聲明為拋出的方式,那么最后異常就會(huì)拋給Java虛擬機(jī)了,由虛擬機(jī)自己去處理。 真正拋出異常對(duì)象的地方都是在程序代碼里面,比如某行代碼出異常了,程序會(huì)自動(dòng)的生成一個(gè)相應(yīng)的異常對(duì)象然后拋出,也可能是我們?cè)诖a里面某些地方自己手動(dòng)的拋出異常對(duì)象,這個(gè)也是先new出來(lái)一個(gè)相應(yīng)的異常對(duì)象,然后拋出(throw);而在方法聲明的時(shí)候?qū)懙谋热鐃hrows Exception,它不是真正的拋出異常對(duì)象,而只是做出一個(gè)聲明,聲明我的這個(gè)方法有可能會(huì)拋出異常,同樣的也告訴調(diào)用這個(gè)方法的調(diào)用端我的這個(gè)方法有可能會(huì)拋出異常,調(diào)用端你也同樣的需要做好拋出異常的準(zhǔn)備(調(diào)用端方法聲明中聲明throws Exception)。就這樣你調(diào)用我,他調(diào)用你,你把我這里拋出的異常繼續(xù)往上拋,他把你這里出來(lái)的異常也繼續(xù)往上拋,就這樣一層層的,一直往上拋,最后把異常拋給了Throwable,由它來(lái)處理。 下面講解自定義異常: 所謂自定義異常,通常就是定義了一個(gè)繼承自Exception類(lèi)的子類(lèi),那么這個(gè)類(lèi)就是一個(gè)自定義異常類(lèi)。通常情況下,我們都會(huì)直接繼承自Exception類(lèi),一般不會(huì)繼承某個(gè)運(yùn)行時(shí)的異常類(lèi)。 自定義異常本身非常簡(jiǎn)單,不難,但是在實(shí)際開(kāi)發(fā)里面幾乎每個(gè)項(xiàng)目或多或少都會(huì)用到自定義異常,比如說(shuō)你做了一件事情,比如用戶在登錄或是什么時(shí)候,用戶名或密碼錯(cuò)了之類(lèi)的,遇到這些情況一方面是可以通過(guò)判斷(if...else…),另外一方面也可以通過(guò)拋異常的方式處理。 自定義異常類(lèi)都需要繼承Exception類(lèi)。 異常2中處理方式的比較:采用拋出的方式,程序一旦出現(xiàn)異常就一定不會(huì)再往下繼續(xù)執(zhí)行了;而采用try…catch…方式,程序一旦出現(xiàn)異常還是可以繼續(xù)往下執(zhí)行。 下面是一個(gè)自定義異常的實(shí)例(重點(diǎn)掌握): package com.shengsiyuan.exception;
/**
* 自定義異常
* 自定義異常類(lèi)都需要繼承Exception類(lèi)。
* 自定義異常一般都有兩個(gè)構(gòu)造方法,一個(gè)不帶參數(shù)的空的構(gòu)造方法,一個(gè)接收一個(gè)字符串參數(shù)的構(gòu)造方法。
* 類(lèi): MyException
* 描述: TODO
* 作者:
* 時(shí)間: Oct 30, 2013 11:02:15 AM
*/
public class MyException extends Exception {
public MyException() {
super();
}
// 這個(gè)方法接收的參數(shù)message一般為異常發(fā)生時(shí)的提示信息。
public MyException(String message) {
// 調(diào)用父類(lèi)Throwable里面接收一個(gè)字符串參數(shù)的構(gòu)造方法,它會(huì)把這個(gè)message的值賦給Throwable里面的detailMessage變量,detailMessage這個(gè)變量一般就是Throwable類(lèi)在處理異常時(shí)(因?yàn)榇蠖鄶?shù)異常最后都是拋給了它,由它來(lái)統(tǒng)一處理,當(dāng)然,利用try...catch...捕獲除外。要么最后拋出到Throwable處理,要么捕獲處理)給出的提示信息。
super(message);
}
} package com.shengsiyuan.exception;
/**
* 自定義異常使用示例
* 類(lèi): ExceptionTest4
* 描述: TODO
* 作者:
* 時(shí)間: Oct 30, 2013 11:52:47 AM
*/
public class ExceptionTest4 {
public void method(String str) throws MyException {
if (null == str) {
// 拋出異常對(duì)象,一層層隨著方法之間的調(diào)用往上拋,一直到最后拋給Throwable來(lái)處理該異常
throw new MyException("傳入的字符串參數(shù)不能為null");
} else {
System.out.println(str);
}
}
/**
* 演示異常的兩種處理方式
* 方法: main
* 描述: TODO
* 作者:
* 時(shí)間: Oct 30, 2013 11:58:22 AM
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 異常的第一種處理方式(拋出)
ExceptionTest4 test4 = new ExceptionTest4();
test4.method("hello");
// 代碼執(zhí)行到這行就會(huì)產(chǎn)生異常并拋出,后面的代碼就不會(huì)再去執(zhí)行了。
test4.method(null);
System.out.println("test");
// // 異常的第二種處理方式
// try {
// ExceptionTest4 test = new ExceptionTest4();
// test.method(null);
// } catch (MyException e) {
// e.printStackTrace();
// } finally {
// System.out.println("異常處理完畢");
// }
// System.out.println("程序執(zhí)行完畢");
}
} Try…catch…finally結(jié)構(gòu)里面的catch塊可以有多個(gè)。每一個(gè)catch塊捕獲著一種特定類(lèi)型的異常。總之凡是被調(diào)用方法有可能拋出的所有異常類(lèi)型(一個(gè)方法是可以拋出多個(gè)異常類(lèi)型,也可以拋出多個(gè)異常之間共有的父類(lèi),比如Exception來(lái)代替多個(gè)異常類(lèi)型來(lái)拋出),你這里在catch塊里面全都要捕獲到,定義一個(gè)catch塊不行就定義兩個(gè),定義兩個(gè)不行就定義三個(gè)(也可以定義一個(gè)多個(gè)異常之間共有的父類(lèi)來(lái)代替多個(gè)異常也可以,比如Exception),一直到都能捕獲到為止。相應(yīng)的異常出現(xiàn)的時(shí)候就進(jìn)入到相應(yīng)類(lèi)型的catch塊里面,但頂多只能有一個(gè)catch塊被執(zhí)行。 對(duì)于異常捕獲來(lái)說(shuō),可以通過(guò)多個(gè)catch來(lái)去捕獲我們的這個(gè)異常,但是一定要注意,他們的這種順序關(guān)系是按照子類(lèi)跟父類(lèi)這種關(guān)系來(lái)排列的。順序是按照子類(lèi)在前父類(lèi)在后的順序來(lái)的,子類(lèi)在前,父類(lèi)在后,表示范圍小的在前面(是針對(duì)多個(gè)catch塊之間的異常類(lèi)存在繼承關(guān)系來(lái)說(shuō)的),如果父類(lèi)型的放在前面那么后面的子類(lèi)型就沒(méi)法去執(zhí)行了就沒(méi)有意義了。如果catch塊和catch塊之間的異常類(lèi)型沒(méi)有關(guān)系不存在繼承關(guān)系,那么誰(shuí)在前誰(shuí)在后都可以。總結(jié)如下: 我們可以使用多個(gè)catch塊來(lái)捕獲異常,這時(shí)需要將父類(lèi)型的catch塊放到子類(lèi)型的catch塊后面,這樣才能保證后續(xù)的catch可能被執(zhí)行,否則子類(lèi)型的catch將永遠(yuǎn)無(wú)法到達(dá),Java 編譯器會(huì)報(bào)編譯錯(cuò)誤;如果多個(gè)catch 塊的異常類(lèi)型是獨(dú)立的(MyException, MyException2),? 那么誰(shuí)前誰(shuí)后都是可以的。 如果try 塊中存在return 語(yǔ)句,那么首先也需要將finally 塊中的代碼執(zhí)行完畢,然后方法再返回(當(dāng)然finally塊后面的代碼不會(huì)執(zhí)行了。這種問(wèn)題很無(wú)聊,根本沒(méi)有什么實(shí)際用處,面試的時(shí)候會(huì)遇到,記住就行。)。 如果try 塊中存在System.exit(0)語(yǔ)句,那么就不會(huì)執(zhí)行finally 塊中的代碼,因?yàn)?System.exit(0)會(huì)終止當(dāng)前運(yùn)行的Java虛擬機(jī),程序會(huì)在虛擬機(jī)終止前結(jié)束執(zhí)行(這種問(wèn)題也很無(wú)聊,沒(méi)用。記住就行。)。 下面示例是一個(gè)實(shí)際開(kāi)發(fā)中經(jīng)常用到的一種使用異常的情況(相當(dāng)于先把當(dāng)前的異常捕獲了,然后轉(zhuǎn)換成自定義的異常拋出,給出用戶自定義的提示處理異常): package com.shengsiyuan.exception;
public class ExceptionTest5 {
public void method() throws MyException {
try {
System.out.println("進(jìn)入到try塊");
int a = 1;
int b = 0;
int c = a / b;
} catch (Exception e) {
System.out.println("異常發(fā)生了");
// 相當(dāng)于把當(dāng)前可能出現(xiàn)的異常類(lèi)型轉(zhuǎn)化了,轉(zhuǎn)化成自己自定義的異常類(lèi)型,然后給用戶相應(yīng)的自定義信息并處理該異常。
throw new MyException("轉(zhuǎn)到自定義異常給用戶提示!");
} finally {
System.out.println("進(jìn)入到finally塊");
}
}
public static void main(String[] args) {
ExceptionTest5 test = new ExceptionTest5();
try {
test.method();
} catch (MyException e) {
e.printStackTrace();
}
}
}
總結(jié)
以上是生活随笔為你收集整理的java经常会出现异常的是,“Java异常Exception”总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 贾跃亭造车梦更近了!法拉第未来FF 91
- 下一篇: 安卓 14 有望支持索尼 PS5 Dua