溫馨提示×

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

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

Java異常的基礎(chǔ)知識(shí)介紹

發(fā)布時(shí)間:2020-06-23 23:03:28 來源:億速云 閱讀:202 作者:Leah 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān)Java異常的基礎(chǔ)知識(shí)介紹,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

一. 異常是什么

異常是指阻止當(dāng)前方法或作用域繼續(xù)執(zhí)行的問題。比如你讀取的文件不存在,數(shù)組越界,進(jìn)行除法時(shí),除數(shù)為0等都會(huì)導(dǎo)致異常。

一個(gè)文件找不到的異常

public class TestException {	
    public static void main(String[] args) throws IOException {	
        InputStream is = new FileInputStream("jaywei.txt");	
        int b;	
        while ((b = is.read()) != -1) {	
        }	
    }	
}

運(yùn)行結(jié)果:

Exception in thread "main" java.io.FileNotFoundException: jaywei.txt (系統(tǒng)找不到指定的文件。)	
    at java.io.FileInputStream.open0(Native Method)	
    at java.io.FileInputStream.open(FileInputStream.java:195)	
    at java.io.FileInputStream.<init>(FileInputStream.java:138)	
    at java.io.FileInputStream.<init>(FileInputStream.java:93)	
    at exception.TestException.main(TestException.java:10)

二. 異常的層次結(jié)構(gòu)

Java異常的基礎(chǔ)知識(shí)介紹

從前從前,有位老人,他的名字叫Throwable,他生了兩個(gè)兒子,大兒子叫Error,二兒子叫Exception。

Error

表示編譯時(shí)或者系統(tǒng)錯(cuò)誤,如虛擬機(jī)相關(guān)的錯(cuò)誤,OutOfMemoryError等,error是無法處理的。

Exception

代碼異常,Java程序員關(guān)心的基類型通常是Exception。它能被程序本身可以處理,這也是它跟Error的區(qū)別。

它可以分為RuntimeException(運(yùn)行時(shí)異常)和CheckedException(可檢查的異常)。

常見的RuntimeException異常:

- NullPointerException 空指針異常	
- ArithmeticException 出現(xiàn)異常的運(yùn)算條件時(shí),拋出此異常	
- IndexOutOfBoundsException 數(shù)組索引越界異常	
- ClassNotFoundException 找不到類異常	
- IllegalArgumentException(非法參數(shù)異常)

常見的 Checked Exception 異常:

- IOException (操作輸入流和輸出流時(shí)可能出現(xiàn)的異常)	
- ClassCastException(類型轉(zhuǎn)換異常類)

 ● Checked Exception就是編譯器要求你必須處置的異常。

 ● 與之相反的是,Unchecked Exceptions,它指編譯器不要求強(qiáng)制處置的異常,它包括Error和RuntimeException 以及他們的子類。

三、異常處理

當(dāng)異常出現(xiàn)后,會(huì)在堆上創(chuàng)建異常對(duì)象。當(dāng)前的執(zhí)行路徑被終止,并且從當(dāng)前環(huán)境中彈出對(duì)異常對(duì)象的引用。這時(shí)候異常處理程序,使程序從錯(cuò)誤狀態(tài)恢復(fù),使程序繼續(xù)運(yùn)行下去。

異常處理主要有拋出異常、捕獲異常、聲明異常。如圖:

Java異常的基礎(chǔ)知識(shí)介紹

捕獲異常
try{	
// 程序代碼	
}catch(Exception e){	
//Catch 塊	
}finaly{	
  //無論如何,都會(huì)執(zhí)行的代碼塊	
}

我們可以通過 try...catch...捕獲異常代碼,再通過 finaly執(zhí)行最后的操作,如關(guān)閉流等操作。

聲明拋出異常

除了 try...catch...捕獲異常,我們還可以通過throws聲明拋出異常。

當(dāng)你定義了一個(gè)方法時(shí),可以用 throws關(guān)鍵字聲明。使用了 throws關(guān)鍵字表明,該方法不處理異常,而是把異常留給它的調(diào)用者處理。是不是覺得TA不負(fù)責(zé)任?

哈哈,看一下demo吧

//該方法通過throws聲明了IO異常。	
 private void readFile() throws IOException {	
        InputStream is = new FileInputStream("jaywei.txt");	
        int b;	
        while ((b = is.read()) != -1) {	
        }	
    }

從方法中聲明拋出的任何異常都必須使用throws子句。

拋出異常

throw關(guān)鍵字作用是拋出一個(gè) Throwable類型的異常,它一般出現(xiàn)在函數(shù)體中。在異常處理中,try語(yǔ)句要捕獲的是一個(gè)異常對(duì)象,其實(shí)此異常對(duì)象也可以自己拋出。

例如拋出一個(gè) RuntimeException 類的異常對(duì)象:

throw new RuntimeException(e);

任何Java代碼都可以通過 Java 的throw語(yǔ)句拋出異常。

注意點(diǎn)

 ● 非檢查異常(Error、RuntimeException 或它們的子類)不可使用 throws 關(guān)鍵字來聲明要拋出的異常。

 ● 一個(gè)方法出現(xiàn)編譯時(shí)異常,就需要 try-catch/ throws 處理,否則會(huì)導(dǎo)致編譯錯(cuò)誤。

四、try-catch-finally-return執(zhí)行順序

try-catch-finally-return 執(zhí)行描述

 ● 如果不發(fā)生異常,不會(huì)執(zhí)行catch部分。

 ● 不管有沒有發(fā)生異常,finally都會(huì)執(zhí)行到。

 ● 即使try和catch中有return時(shí),finally仍然會(huì)執(zhí)行

 ● finally是在return后面的表達(dá)式運(yùn)算完后再執(zhí)行的。(此時(shí)并沒有返回運(yùn)算后的值,而是先把要返回的值保存起來,若finally中無return,則不管finally中的代碼怎么樣,返回的值都不會(huì)改變,仍然是之前保存的值),該情況下函數(shù)返回值是在finally執(zhí)行前確定的)

 ● finally部分就不要return了,要不然,就回不去try或者catch的return了。

看一個(gè)例子

 public static void main(String[] args) throws IOException {	
        System.out.println("result:" + test());	
    }	
    private static int test() {	
        int temp = 1;	
        try {	
            System.out.println("start execute try,temp is:"+temp);	
            return ++temp;	
        } catch (Exception e) {	
            System.out.println("start execute catch temp is: "+temp);	
            return ++temp;	
        } finally {	
            System.out.println("start execute finally,temp is:" + temp);	
            ++temp;	
        }	
    }

運(yùn)行結(jié)果:

start execute try,temp is:1	
start execute finally,temp is:2	
result:2

分析

 ● 先執(zhí)行try部分,輸出日志,執(zhí)行 ++temp表達(dá)式,temp變?yōu)?,這個(gè)值被保存起來。

 ● 因?yàn)闆]有發(fā)生異常,所以catch代碼塊跳過。

 ● 執(zhí)行finally代碼塊,輸出日志,執(zhí)行 ++temp表達(dá)式.

 ● 返回try部分保存的值2.

五、Java異常類的幾個(gè)重要方法

先來喵一眼異常類的所有方法,如下圖:

Java異常的基礎(chǔ)知識(shí)介紹

getMessage
Returns the detail message string of this throwable.

getMessage會(huì)返回Throwable的 detailMessage屬性,而 detailMessage就表示發(fā)生異常的詳細(xì)消息描述。

舉個(gè)例子, FileNotFoundException異常發(fā)生時(shí),這個(gè) detailMessage就包含這個(gè)找不到文件的名字。

getLocalizedMessage
Creates a localized description of this throwable.Subclasses may override this	
method in order to produce alocale-specific message. For subclasses that do not	
override thismethod, the default implementation returns the same result	
as getMessage()

throwable的本地化描述。子類可以重寫此方法,以生成特定于語(yǔ)言環(huán)境的消息。對(duì)于不覆蓋此方法的子類,默認(rèn)實(shí)現(xiàn)返回與相同的結(jié)果 getMessage()。

getCause
Returns the cause of this throwable or null if thecause is nonexistent or unknown.

返回此可拋出事件的原因,或者,如果原因不存在或未知,返回null。

printStackTrace
Prints this throwable and its backtrace to thestandard error stream.	
The first line of output contains the result of the toString() method for	
this object.Remaining lines represent data previously recorded by the	
method fillInStackTrace().

該方法將堆棧跟蹤信息打印到標(biāo)準(zhǔn)錯(cuò)誤流。

輸出的第一行,包含此對(duì)象toString()方法的結(jié)果。剩余的行表示,先前被方法fillInStackTrace()記錄的數(shù)據(jù)。如下例子:

 java.lang.NullPointerException	
         at MyClass.mash(MyClass.java:9)	
         at MyClass.crunch(MyClass.java:6)	
         at MyClass.main(MyClass.java:3)

六、自定義異常

自定義異常通常是定義一個(gè)繼承自 Exception 類的子類。

那么,為什么需要自定義異常?

 ● Java提供的異常體系不可能預(yù)見所有的錯(cuò)誤。

 ● 業(yè)務(wù)開發(fā)中,使用自定義異常,可以讓項(xiàng)目代碼更加規(guī)范,也便于管理。

下面是我司自定義異常類的一個(gè)簡(jiǎn)單demo

public class BizException extends Exception {	
    //錯(cuò)誤信息	
    private String message;	
    //錯(cuò)誤碼	
    private String errorCode;	
    public BizException() {	
    }	
    public BizException(String message, String errorCode) {	
        this.message = message;	
        this.errorCode = errorCode;	
    }	
    @Override	
    public String getMessage() {	
        return message;	
    }	
    public void setMessage(String message) {	
        this.message = message;	
    }	
    public String getErrorCode() {	
        return errorCode;	
    }	
    public void setErrorCode(String errorCode) {	
        this.errorCode = errorCode;	
    }	
}

跑個(gè)main方測(cè)試一下

public class TestBizException {	
    public static void testBizException() throws BizException {	
        System.out.println("throwing BizException from testBizException()");	
        throw new BizException("100","哥,我錯(cuò)了");	
    }	
    public static void main(String[] args) {	
        try {	
            testBizException();	
        } catch (BizException e) {	
            System.out.println("自己定義的異常");	
            e.printStackTrace();	
        }	
    }	
}

運(yùn)行結(jié)果:

exception.BizException: 100	
throwing BizException from testBizException()	
自己定義的異常	
    at exception.TestBizException.testBizException(TestBizException.java:7)	
    at exception.TestBizException.main(TestBizException.java:12)

七、Java7 新的 try-with-resources語(yǔ)句

try-with-resources,是Java7提供的一個(gè)新功能,它用于自動(dòng)資源管理。

 ● 資源是指在程序用完了之后必須要關(guān)閉的對(duì)象。

 ● try-with-resources保證了每個(gè)聲明了的資源在語(yǔ)句結(jié)束的時(shí)候會(huì)被關(guān)閉

 ● 什么樣的對(duì)象才能當(dāng)做資源使用呢?只要實(shí)現(xiàn)了java.lang.AutoCloseable接口或者java.io.Closeable接口的對(duì)象,都OK。

try-with-resources出現(xiàn)之前

try{	
    //open resources like File, Database connection, Sockets etc	
} catch (FileNotFoundException e) {	
    // Exception handling like FileNotFoundException, IOException etc	
}finally{	
    // close resources	
}

Java7, try-with-resources出現(xiàn)之后,使用資源實(shí)現(xiàn)

try(// open resources here){	
    // use resources	
} catch (FileNotFoundException e) {	
    // exception handling	
}	
// resources are closed as soon as try-catch block is executed.

Java7使用資源demo

public class Java7TryResourceTest {	
    public static void main(String[] args) {	
        try (BufferedReader br = new BufferedReader(new FileReader(	
                "C:/jaywei.txt"))) {	
            System.out.println(br.readLine());	
        } catch (IOException e) {	
            e.printStackTrace();	
        }	
    }	
}

使用了 try-with-resources的好處

 ● 代碼更加優(yōu)雅,行數(shù)更少。

 ● 資源自動(dòng)管理,不用擔(dān)心內(nèi)存泄漏問題。

八、異常鏈

我們常常會(huì)想要在捕獲一個(gè)異常后拋出另一個(gè)異常,并且希望把原始異常的信息保存下來,這被稱為異常鏈

throw 拋出的是一個(gè)新的異常信息,這樣會(huì)導(dǎo)致原有的異常信息丟失。在JDk1.4以前,程序員必須自己編寫代碼來保存原始異常信息?,F(xiàn)在所有 Throwable 子類在構(gòu)造器中都可以接受一個(gè) cause(異常因由) 對(duì)象作為參數(shù)。

這個(gè) cause就用來表示原始異常,這樣通過把原始異常傳遞給新的異常,使得即使當(dāng)前位置創(chuàng)建并拋出了新的異常,也能通過這個(gè)異常鏈追蹤到異常最初發(fā)生的位置。

使用方式如下:

public class TestChainException {	
    public void readFile() throws MyException{	
        try {	
            InputStream is = new FileInputStream("jay.txt");	
            Scanner in = new Scanner(is);	
            while (in.hasNext()) {	
                System.out.println(in.next());	
            }	
        } catch (FileNotFoundException e) {	
            //e 保存異常信息	
            throw new MyException("文件在哪里呢", e);	
        }	
    }	
    public void invokeReadFile() throws MyException{	
        try {	
            readFile();	
        } catch (MyException e) {	
            //e 保存異常信息	
            throw new MyException("文件找不到", e);	
        }	
    }	
    public static void main(String[] args) {	
        TestChainException t = new TestChainException();	
        try {	
            t.invokeReadFile();	
        } catch (MyException e) {	
            e.printStackTrace();	
        }	
    }	
}	
//MyException 構(gòu)造器	
public MyException(String message, Throwable cause) {	
        super(message, cause);	
    }

運(yùn)行結(jié)果:

Java異常的基礎(chǔ)知識(shí)介紹

我們可以看到異常信息有保存下來的,如果把cause(也就是FileNotFoundException 的e)去掉呢,看一下運(yùn)行結(jié)果:

Java異常的基礎(chǔ)知識(shí)介紹

可以發(fā)現(xiàn),少了 Throwablecause,原始異常信息不翼而飛了。

九、異常匹配

拋出異常的時(shí)候,異常處理系統(tǒng)會(huì)按照代碼的書寫順序找出"最近"的處理程序。找到匹配的處理程序之后,它就認(rèn)為異常將得到處理,然后就不再繼續(xù)查找。

查找的時(shí)候并不要求拋出的異常同處理程序的異常完全匹配。派生類的對(duì)象也可以配備其基類的處理程序

看demo

package exceptions;	
//: exceptions/Human.java	
// Catching exception hierarchies.	
class Annoyance extends Exception {}	
class Sneeze extends Annoyance {}	
public class Human {	
  public static void main(String[] args) {	
    // Catch the exact type:	
    try {	
      throw new Sneeze();	
    } catch(Sneeze s) {	
      System.out.println("Caught Sneeze");	
    } catch(Annoyance a) {	
      System.out.println("Caught Annoyance");	
    }	
    // Catch the base type:	
    try {	
      throw new Sneeze();	
    } catch(Annoyance a) {	
      System.out.println("Caught Annoyance");	
    }	
  }	
}

運(yùn)行結(jié)果:

Java異常的基礎(chǔ)知識(shí)介紹

catch(Annoyance a)會(huì)捕獲Annoyance以及所有從它派生的異常。捕獲基類的異常,就可以匹配所有派生類的異常

try {	
      throw new Sneeze();	
    } catch(Annoyance a) {	
    } catch(Sneeze s) { //這句編譯器會(huì)報(bào)錯(cuò),因?yàn)楫惓R延汕懊鎐atch子句處理	
    }

十、Java常見異常

NullPointerException

空指針異常,最常見的一個(gè)異常類。簡(jiǎn)言之,調(diào)用了未經(jīng)初始化的對(duì)象或者是不存在的對(duì)象,就會(huì)產(chǎn)生該異常。

ArithmeticException

算術(shù)異常類,程序中出現(xiàn)了除數(shù)為0這樣的運(yùn)算,就會(huì)出現(xiàn)這樣的異常。

ClassCastException

類型強(qiáng)制轉(zhuǎn)換異常,它是JVM在檢測(cè)到兩個(gè)類型間轉(zhuǎn)換不兼容時(shí)引發(fā)的運(yùn)行時(shí)異常。

ArrayIndexOutOfBoundsException

數(shù)組下標(biāo)越界異常,跟數(shù)組打交道時(shí),需要注意一下這個(gè)異常。

FileNotFoundException

文件未找到異常,一般是要讀或者寫的文件,找不到,導(dǎo)致該異常。

SQLException

操作數(shù)據(jù)庫(kù)異常,它是Checked Exception(檢查異常);

IOException

IO異常,一般跟讀寫文件息息相關(guān),它也是Checked Exception(檢查異常)。平時(shí)讀寫文件,記得IO流關(guān)閉!

NoSuchMethodException

方法未找到異常

NumberFormatException

字符串轉(zhuǎn)換為數(shù)字異常

總結(jié)

這個(gè)總結(jié)獨(dú)辟蹊徑,以幾道經(jīng)典異常面試題結(jié)束吧,以幫助大家復(fù)習(xí)一下,嘻嘻。

 ● java 異常有哪幾種,特點(diǎn)是什么?(知識(shí)點(diǎn)二可答)

 ● 什么是Java中的異常?(知識(shí)點(diǎn)一可答)

 ● error和exception有什么區(qū)別?(知識(shí)點(diǎn)二可答)

 ● 什么是異常鏈?(知識(shí)點(diǎn)八可答)

 ● try-catch-finally-return執(zhí)行順序(知識(shí)點(diǎn)四可答)

 ● 列出常見的幾種RunException (知識(shí)點(diǎn)二可答)

 ● Java異常類的重要方法是什么?(知識(shí)點(diǎn)五可答)

 ● error和exception的區(qū)別,CheckedException,RuntimeException的區(qū)別。(知識(shí)點(diǎn)二可答)

 ● 請(qǐng)列出5個(gè)運(yùn)行時(shí)異常。(知識(shí)點(diǎn)二可答)

 ● Java 7 新的 try-with-resources 語(yǔ)句(知識(shí)點(diǎn)七可答)

 ● 怎么自定義異常?(知識(shí)點(diǎn)六可答)

 ● 說一下常見異常以及產(chǎn)生原因(知識(shí)點(diǎn)十可答)

 ● 談?wù)劗惓Fヅ洌ㄖR(shí)點(diǎn)九可答)

 ● 談?wù)劗惓L幚恚ㄖR(shí)點(diǎn)三可答)

關(guān)于Java異常的基礎(chǔ)知識(shí)介紹就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(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