異常簡(jiǎn)介
- 異常的定義
- 運(yùn)行期間出現(xiàn)的錯(cuò)誤鸥诽,而不是編譯時(shí)的語(yǔ)法錯(cuò)誤
- 例如,
- 打開(kāi)一個(gè)不存在的文件
- 網(wǎng)絡(luò)連接中斷
- 操作數(shù)組越界等
- 異常的定義
- 示 例 數(shù)組越界異常
public class excption_sample {
public static void main(String args[ ]){
int i = 0;
String greetings[ ] = {"Hello World",
"Hello Dingdang",
"Hello Kitty"};
while(i<4){
System.out.println(greetings[i]);
i++;
}
}
}
異常類(lèi)的繼承關(guān)系
- 異常的繼承樹(shù)
-
異常類(lèi)的體系結(jié)構(gòu)
-
Object 類(lèi)的直接子類(lèi)Throwable描述了所有被虛擬機(jī)拋出的非正常狀況秉氧。一般情況下很少用Throwable仿滔,而是使用它的兩個(gè)子類(lèi)Error屑宠、Exception侨把。
- Error類(lèi)特指應(yīng)用程序在運(yùn)行期間發(fā)生的嚴(yán)重錯(cuò)誤秋柄。如:虛擬機(jī)內(nèi)存用盡省店、堆棧溢出等等懦傍。一般情況下這種錯(cuò)誤都是災(zāi)難性的,所以沒(méi)有必要使用異常處理機(jī)制處理Error虚吟。
- Exception類(lèi)有幾十個(gè)子類(lèi),描述了不同類(lèi)型的異常唱蒸,其中:
- 以RuntimeException為代表的一些類(lèi)神汹,稱(chēng)為非檢查性異常(unchecked Exception)古今,
- 以IOException為代表的一些類(lèi)為檢查性異常(checked Exception)沧卢。所謂的檢查和非檢查是指編譯器在編譯時(shí)是否檢查披诗。如果代碼中存在檢查性異常,必須進(jìn)行異常處理宪摧,否則編譯時(shí)不能通過(guò);而非檢查性異常編譯時(shí)不進(jìn)行檢查沿彭,到運(yùn)行時(shí)才會(huì)顯現(xiàn)喉刘。
-
異常類(lèi)型
-
檢查性異常(checked exception)
- 若系統(tǒng)運(yùn)行時(shí)可能產(chǎn)生該類(lèi)異常漆弄,則必須寫(xiě)出相應(yīng)的處理代碼睦裳,否則無(wú)法通過(guò)編譯
- 非RuntimeException異常
-
非檢查性異常(unchecked exception)
- 若系統(tǒng)運(yùn)行時(shí)可能產(chǎn)生該類(lèi)異常撼唾,則不必在程序中聲明對(duì)該類(lèi)異常的處理,就可以編譯執(zhí)行
- RuntimeException:運(yùn)行時(shí)異常
-
Java為何分別處理這兩類(lèi)異常?
一般我們不在 代碼中處理非檢查性異常肺素,這類(lèi)異常都在運(yùn)行時(shí)拋出恨锚。原因主要是由于程序員經(jīng)驗(yàn)不足或是思維不縝密造成宇驾。如:數(shù)組越界異常(ArrayIndexOutOfBoundsException)猴伶、整數(shù)除以0異常(ArithmeticException)等他挎,這類(lèi)異常其實(shí)就是我們通常說(shuō)的bug。所以呢撞,這類(lèi)異常應(yīng)通過(guò)反復(fù)測(cè)試盡量避免殊霞,而不應(yīng)該靠異常處理機(jī)制來(lái)解決。
檢查性異常不同绷蹲,就算程序員再有經(jīng)驗(yàn)棒卷,也是難以避免。如:用戶(hù)連接數(shù)據(jù)庫(kù)的異常(SQLException)祝钢,如果是由于數(shù)據(jù)庫(kù)服務(wù)器沒(méi)有啟動(dòng)或是網(wǎng)絡(luò)中斷引起的比规,我們程序員是無(wú)法避免的。又如:程序要讀取光盤(pán)中的文件拦英,而用戶(hù)忘記插入光盤(pán)苞俘,此時(shí)則拋出文件沒(méi)找到異常(FileNotFoundException),程序員也無(wú)法避免龄章。
綜上吃谣,異常處理機(jī)制主要處理檢查性異常而不是非檢查性異常和Error。
非檢查性異常 | 說(shuō)明 |
---|---|
RuntimeException | java.lang包中多數(shù)異常的基類(lèi) |
ArithmeticException | 算術(shù)錯(cuò)誤做裙,如除以 0 |
IllegalArgumentException | 方法收到非法參數(shù) |
ArrayIndexOutOfBoundsException | 數(shù)組下標(biāo)出界 |
NullPointerException | 試圖訪(fǎng)問(wèn) null 對(duì)象引用 |
檢查性異常 | 說(shuō)明 |
---|---|
ClassNotFoundException | 無(wú)法找到想要?jiǎng)?chuàng)建對(duì)象的類(lèi)文件 |
IOException | I/O 異常的根類(lèi) |
FileNotFoundException | 不能找到文件 |
EOFException | 文件結(jié)束 |
IllegalAccessException | 對(duì)類(lèi)的訪(fǎng)問(wèn)被拒絕 |
NoSuchMethodException | 請(qǐng)求的方法不存在 |
InterruptedException | 線(xiàn)程中斷 |
異常處理機(jī)制
- 異常的處理過(guò)程
在Java程序執(zhí)行過(guò)程中如果出現(xiàn)異常事件岗憋,系統(tǒng)會(huì)發(fā)出異常報(bào)告,這時(shí)系統(tǒng)將生成一個(gè)異常類(lèi)對(duì)象锚贱,異常類(lèi)對(duì)象封裝了異常事件的信息并將其提交給Java運(yùn)行時(shí)系統(tǒng)
-
Java 中可用于處理異常的兩種方式:
- 自行處理:可能引發(fā)異常的語(yǔ)句封入在 try 塊內(nèi)仔戈,而處理異常的相應(yīng)語(yǔ)句則封入在 catch 塊內(nèi)。
- 回避異常:在方法聲明中包含 throws 子句,通知潛在調(diào)用者监徘,如果發(fā)生了異常晋修,必須由調(diào)用者處理。
try…catch語(yǔ)句
示例 Exception_sample_1.java
public class excption_sample {
public static void main(String args[ ]){
int i = 0;
String greetings[ ] = {"Hello World",
"Hello Dingdang",
"Hello Kitty"};
try{ //try{}表示可能發(fā)生異常的語(yǔ)句
while(i<4){
System.out.println(greetings[i]);
i++;
}
}catch(ArrayIndexOutOfBoundsException e){//catch( )內(nèi)的參數(shù)異常類(lèi)對(duì)象的聲明
System.out.println(“數(shù)組越界異郴丝”);//catch{}內(nèi)的語(yǔ)句是對(duì)異常的處理
}
}
}
- catch塊墓卦,是用來(lái)捕獲并處理try塊拋出的異常的代碼塊。沒(méi)有try塊户敬,catch塊不能單獨(dú)存在落剪。我們可以有多個(gè)catch塊,以捕獲不同類(lèi)型的異常
- 如果程序拋出多個(gè)不同類(lèi)型的異常尿庐,我們需要多個(gè)catch()語(yǔ)句來(lái)處理忠怖。
- 和特殊異常類(lèi)相關(guān)聯(lián)的catch()塊必須寫(xiě)在和普通異常類(lèi)相關(guān)聯(lián)的catch()之前。
- try{…}和catch( ){…}之間不可以添加任何代碼
- 每次try塊有異常拋出抄瑟,系統(tǒng)會(huì)試著從上到下往每個(gè)catch塊中傳參凡泣,直到遇到一個(gè)類(lèi)型匹配的catch塊為止。
- 如上示例中最后一個(gè)catch塊中的形參為Exception類(lèi)型皮假,它是所有異常類(lèi)的父類(lèi)鞋拟,任何異常都可以傳參到該塊中,該塊可以處理任何類(lèi)型的異常钞翔。因此严卖,這個(gè)catch塊只能放到最后面,否則所有的異常都被它處理了布轿,其他的catch塊就不能分門(mén)別類(lèi)的起作用了哮笆。
- 如果編寫(xiě)過(guò)程中我們違背了這一點(diǎn),會(huì)產(chǎn)生編譯錯(cuò)誤:
exception java.io.ArrayOutOfBoundsException has already bean caught
- 一般一個(gè)catch塊中是專(zhuān)門(mén)處理異常的代碼汰扭,在程序中這里還可以是記錄日志的語(yǔ)句稠肘,當(dāng)發(fā)生異常時(shí)記錄該日志,無(wú)異常時(shí)將不會(huì)記錄萝毛。
異常處理機(jī)制——Java7特性
- catch表達(dá)式調(diào)整
- JDK 7中项阴,單個(gè)catch塊可以處理多個(gè)異常類(lèi)型
try {
......
} catch(ClassNotFoundException|SQLException ex) {
ex.printStackTrace();
}
- catch表達(dá)式調(diào)整
- 這種用法是不包括異常的子類(lèi)型的。比如說(shuō)笆包,下面這個(gè)多個(gè)異常的捕獲語(yǔ)句就會(huì)拋出編譯錯(cuò)誤:
try {
......
} catch (FileNotFoundException | IOException ex) {
ex.printStackTrace();
}
- finally 語(yǔ)句
- finally語(yǔ)句放在try …catch語(yǔ)句后
- fianlly語(yǔ)句中的代碼塊不管異常是否被捕獲總是要執(zhí)行
- 通常在finally語(yǔ)句中可以進(jìn)行資源的清除操作环揽,如:關(guān)閉打開(kāi)文件、刪除臨時(shí)文件
- 對(duì)應(yīng)finally代碼中的語(yǔ)句庵佣,即使try代碼塊和catch代碼塊中使用了return語(yǔ)句退出當(dāng)前方法或般若break跳出某個(gè)循環(huán)歉胶,相關(guān)的finally代碼塊都有執(zhí)行。
- 當(dāng)try或catch代碼塊中執(zhí)行了System.exit(0)時(shí)巴粪,finally代碼塊中的內(nèi)容不被執(zhí)行
catch (ArrayIndexOutOfBoundsException e) {
System.out.println(“Out of Bounds!”);
return;
}
catch (RuntimeException e) {
System.out.println(“Runtime Exception!”);}
catch (Exception e) {
System.out.println(“Exception!”);
}finally{
System.out.println("program is running into finally!");//無(wú)論是否捕獲異常通今,系統(tǒng)都會(huì)執(zhí)行該語(yǔ)句
}
- throws關(guān)鍵字
- 如果一個(gè)方法中的語(yǔ)句執(zhí)行時(shí)可能生成某種異常粥谬,但是并不能確定如何處理,則可以在程序所在的函數(shù)聲明后辫塌,使用throws關(guān)鍵字拋出異常
class ThrowsDemo{
public void proc( ) throws IOException{
System.out.println("inside proc");
}
}
- 位置:函數(shù)參數(shù)列表的后面
- throws關(guān)鍵字后面漏策,可以跟多個(gè)異常,中間用逗號(hào)分割
- throws關(guān)鍵字拋出的異常臼氨,由調(diào)用該函數(shù)的函數(shù)處理掺喻。
- 方法中如果用throws關(guān)鍵字拋出:
- 非檢查性異常:上一級(jí)去除異常,直到不拋出異常一也;
- 檢查性異常
- 在調(diào)用該函數(shù)內(nèi)try-catch巢寡,把異常處理掉喉脖。那么不往上一級(jí)拋出異常椰苟,程序正常執(zhí)行,上一級(jí)方法并不知道曾經(jīng)產(chǎn)生異常树叽。
- 用throws聲明方法拋出異常舆蝴,不進(jìn)行處理。誰(shuí)調(diào)用誰(shuí)負(fù)責(zé)處理
- 覆蓋方法拋出異常時(shí)题诵,可以?huà)伋雠c被覆蓋方法相同的異辰嗾蹋或者被覆蓋方法異常的子類(lèi)異常。
public class ThrowTest
{
public void createFile(String path) throws IOException{
File f= new File(path);
f.createNewFile();
}
public static void main(String[] args){
ThrowTest tt = new ThrowTest();
try{
tt.createFile("c:/abc.txt");
}catch(IOException ex){
ex.printStackTrace();
}
}
}
- throw語(yǔ)句
- 異常是通過(guò)關(guān)鍵字 throw 拋出性锭,程序可以用throw語(yǔ)句引發(fā)明確的異常赠潦。如:
void doA() throws Exception1 {
try {
.....
}catch(Exception1 e){
throw e;
}catch(Exception2 e){
System.out.println("出錯(cuò)了");
}
}
- throw語(yǔ)句用在方法體內(nèi),表示拋出異常,由方法體內(nèi)的語(yǔ)句處理。不能單獨(dú)使用草冈,要么和try.. catch…一起使用她奥,要么和throws一起使用。
- throw語(yǔ)句的操作數(shù)一定是Throwable類(lèi)類(lèi)型或Throwable子類(lèi)類(lèi)型的一個(gè)對(duì)象
public class ThrowTest
{
public void createFile(String path) throws IOException{
File f= new File(path);
try{
f.createNewFile();
}catch(IOException ie){
ie.printStackTrace();
throw ie; //再次拋出
}
}
public static void main(String[] args){
ThrowTest tt = new ThrowTest();
try{
tt.createFile("c:/abc.txt");
}catch(IOException ex){
ex.printStackTrace();
}
}
}
示例代碼:
package 異常的處理;
public class TestExceptionHandler {
public int sum(int a,int b) {
return a + b;
}
public static void main(String[] args) throws ClassNotFoundException {//2.消積處理
//模擬異常怎棱,看怎么處理哩俭?
//2.消積處理:異常拋出虛擬機(jī),程序終止
Class.forName("java.a.Date");
//1.積極處理:程序繼續(xù)執(zhí)行完畢
// try {
// Class.forName("java.a.Date");
// } catch (Exception e) {
// e.printStackTrace();
// }
// for (int i = 0; i < 100; i++) {
// System.out.println(i);
// }
}
}
package 異常的處理;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestExceptionHandler2 {
public static void main(String[] args){
File file = new File("e:\\HelloWorld.java");
FileInputStream is = null;
try {
is = new FileInputStream(file);
int result = is.read();//根據(jù)提示選擇clause to surrounding by
Class.forName("java.a.b");
// } catch (ClassNotFoundException | IOException e) {//Java7對(duì)catch的改寫(xiě)拳恋,可以多個(gè)異常同時(shí)寫(xiě)
// e.printStackTrace();
} catch (FileNotFoundException e) {
System.out.println("a");
e.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
System.out.println("b");
e.printStackTrace();
//1.finally語(yǔ)句塊有什么 作用凡资?
// 用于釋放資源,即使代碼拋出異常谬运,
// finally語(yǔ)句塊中的代碼也會(huì)執(zhí)行
}finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//2.final finalize finally 有什么區(qū)別隙赁?
/**
* final 修飾的類(lèi)不能有子類(lèi)
* 修飾的方法不能重寫(xiě)
* 修飾的變量不能重新賦值,叫常量
* finalize:如果發(fā)現(xiàn)有垃圾對(duì)象的話(huà)就會(huì)調(diào)用finalize()方法梆暖,釋放它所占用的內(nèi)存
* finally: 確保我們程序當(dāng)中有些釋放資源的方法能夠執(zhí)行伞访,
* 一般跟在try catch語(yǔ)句塊后面
*/
}
}
package 異常的處理;
import java.io.File;
import java.io.FileInputStream;
public class TestRuntimeException {
public static void main(String[] args) throws Exception {//消積處理
// String a = null;
// System.out.println(a.length());//java.lang.NullPointerException
File file = new File("e:\\HelloWorld.java");
// try {
// FileInputStream is = new FileInputStream(file);
//
// int result = is.read();
// } catch (Exception e) {
// e.printStackTrace();
// }//積極處理
FileInputStream is = new FileInputStream(file);
int result = is.read();
}
}
package 異常的處理;
public class Test {
public static void main(String[] args) {
// double p = "";//這是語(yǔ)法錯(cuò)誤,稱(chēng)不上異常
/**
* 異常:
* 代碼運(yùn)行期間出現(xiàn)的錯(cuò)誤
* 打開(kāi)一個(gè)不存在的文件
* 網(wǎng)絡(luò)連接中斷
* 操作數(shù)組越界等
*/
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
// int b = 0;
// if(b != 0) {
// int a = 10 / b;
// }
try {
Class.forName("java.a.b");
System.out.println("a");
} catch (Exception e) {
System.out.println("b");
e.printStackTrace();
}finally {
System.out.println("d");
}
System.out.println("c");
for (int i = 0; i < 10; i++) {
System.out.println("i: " + i);
}
}
}
以上就是我關(guān)于 Java-自定義異常類(lèi) 知識(shí)點(diǎn)的整理與總結(jié)的全部?jī)?nèi)容式廷,另附源碼
分割線(xiàn)
博主為咯學(xué)編程:父母不同意學(xué)編程咐扭,現(xiàn)已斷絕關(guān)系;戀人不同意學(xué)編程,現(xiàn)已分手;親戚不同意學(xué)編程,現(xiàn)已斷絕來(lái)往;老板不同意學(xué)編程,現(xiàn)已失業(yè)三十年蝗肪。袜爪。。薛闪。辛馆。。如果此博文有幫到你歡迎打賞豁延,金額不限昙篙。。诱咏。