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

學(xué)習(xí)Java之異常到底該如何捕獲和處理

 更新時(shí)間:2023年08月10日 08:23:37   作者:一一哥Sun  
我們知道,Java的異常處理是通過(guò)5個(gè)關(guān)鍵字來(lái)實(shí)現(xiàn)的,即try、catch、throw、throws和finally,try?catch語(yǔ)句用于捕獲并處理異常,但具體該怎么捕獲異常,怎么拋出異常,什么時(shí)候拋,什么時(shí)候捕,感興趣的小伙伴跟著小編一起來(lái)看看吧

一. 捕獲和處理異常

1. 概述

在Java中,如果某行或某幾行代碼有可能會(huì)拋出異常,我們此時(shí)就可以用try ... catch ... finally進(jìn)行捕獲處理。把可能發(fā)生異常的語(yǔ)句放在try { ... }語(yǔ)句中,然后使用catch語(yǔ)句捕獲對(duì)應(yīng)的Exception及其子類(lèi),把必須執(zhí)行的代碼放在finally語(yǔ)句中。接下來(lái)我們就來(lái)看看具體的代碼實(shí)現(xiàn)吧。

2. try-catch結(jié)構(gòu)

2.1 基本語(yǔ)法

首先我們來(lái)看看try-catch的基本語(yǔ)法:

try {
    // 可能發(fā)生異常的語(yǔ)句
} catch(Exception e) {
    // 處理異常語(yǔ)句
}

在上面的語(yǔ)法中,我們要把可能引發(fā)異常的語(yǔ)句封裝在try語(yǔ)句塊中,用于捕獲可能發(fā)生的異常。catch語(yǔ)句里的( )中,要傳入與try語(yǔ)句里匹配的異常類(lèi),指明catch語(yǔ)句可以處理的異常類(lèi)型。

也就是說(shuō),如果此時(shí)try語(yǔ)句塊中發(fā)生了某個(gè)異常,那么這個(gè)相應(yīng)的異常對(duì)象就會(huì)被拋出,產(chǎn)生異常的這行代碼之后的其余代碼就不會(huì)再被執(zhí)行。然后catch語(yǔ)句就開(kāi)始執(zhí)行,把try中拋出的異常對(duì)象進(jìn)行捕獲并處理。
當(dāng)然,如果try語(yǔ)句塊中沒(méi)有發(fā)生異常,那么try里的代碼就會(huì)正常執(zhí)行結(jié)束,而后面的catch就會(huì)被跳過(guò)。

這里我們需要注意:try...catch與if...else是不一樣的,try后面的花括號(hào){ }不可以省略,即便try中只有一行代碼。同樣的,catch的花括號(hào) { } 也不可以省略。另外,try語(yǔ)句塊中聲明的變量屬于局部變量,它只在try中有效,其它地方不能訪問(wèn)該變量。

2.2 代碼實(shí)現(xiàn)

接下來(lái)設(shè)計(jì)一個(gè)代碼案例,來(lái)講解try-catch的用法:

/**
 * @author
 */
public class Demo01 {
    public static void main(String[] args) {
        //定義一個(gè)長(zhǎng)度為3的數(shù)組
        int[] array = new int[3];
        try {
            //索引超出了數(shù)組長(zhǎng)度,將會(huì)引發(fā)ArrayIndexOutOfBoundsException數(shù)組下標(biāo)越界異常
            array[3] = 1; 
            //發(fā)生異常后,這行代碼并不會(huì)執(zhí)行
            System.out.println("數(shù)組:" + array.toString());
        } catch (ArrayIndexOutOfBoundsException e) {
            //指出異常的類(lèi)型、性質(zhì)、棧層次及出現(xiàn)在程序中的位置
            e.printStackTrace();
            //輸出錯(cuò)誤的原因及性質(zhì)
            System.out.println("數(shù)組越界:" + e.getMessage());
            //輸出異常的類(lèi)型與性質(zhì)
            System.out.println("數(shù)組越界:" + e.toString());
        }
    }
}

在上面這段代碼中,小編在try語(yǔ)句中創(chuàng)建了一個(gè)長(zhǎng)度為3的整數(shù)數(shù)組,并嘗試著將第4個(gè)位置上的元素值設(shè)為1。由于數(shù)組越界,這會(huì)引發(fā)代碼故障,java會(huì)拋出一個(gè)ArrayIndexOutOfBoundsException異常。由于發(fā)生了異常,所以后面的數(shù)組輸出語(yǔ)句就不會(huì)被執(zhí)行。

而我們?cè)赾atch中接收了ArrayIndexOutOfBoundsException異常,這個(gè)異常與try中拋出的異常是一致的,所以代碼會(huì)跳轉(zhuǎn)到catch中進(jìn)行異常的處理。另外在上面的處理代碼塊中,我們可以通過(guò)Exception異常對(duì)象的以下方法,來(lái)獲取到相應(yīng)的異常信息。

  • printStackTrace()方法:輸出異常棧信息,指出異常的類(lèi)型、性質(zhì)、棧層次及出現(xiàn)在程序中的位置;
  • getMessage()方法:輸出錯(cuò)誤的性質(zhì);
  • toString()方法:輸出異常的類(lèi)型與性質(zhì)。

3. 多重catch結(jié)構(gòu)

我們?cè)诰帉?xiě)java代碼時(shí),多行語(yǔ)句有可能會(huì)產(chǎn)生多個(gè)不同的異常,你們面對(duì)這個(gè)多個(gè)異常該怎么處理呢?其實(shí)我們可以使用多重catch語(yǔ)句來(lái)分別處理多個(gè)異常。

3.1 基本語(yǔ)法

多重catch語(yǔ)句的基本語(yǔ)法格式如下:

try {
    // 可能會(huì)發(fā)生異常的語(yǔ)句
} catch(ExceptionType e) {
    // 處理異常語(yǔ)句
} catch(ExceptionType e) {
    // 處理異常語(yǔ)句
} catch(ExceptionType e) {
    // 處理異常語(yǔ)句
	...
}

當(dāng)存在多個(gè)catch代碼塊時(shí),只要有一個(gè)catch代碼塊捕獲到一個(gè)異常,其它的catch代碼塊就不再進(jìn)行匹配。但是我們要注意,當(dāng)捕獲的多個(gè)異常類(lèi)之間存在父子關(guān)系時(shí),一般是先捕獲子類(lèi),再捕獲父類(lèi)。所以我們?cè)诰帉?xiě)代碼時(shí),要把子類(lèi)異常放在父類(lèi)異常的前面,否則子類(lèi)就會(huì)捕獲不到。

3.2 代碼實(shí)現(xiàn)

接下來(lái)給大家設(shè)計(jì)了一個(gè)利用IO流讀取文件內(nèi)容的案例,這段代碼就可能會(huì)出現(xiàn)兩個(gè)異常。

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
 * @author 一一哥Sun
 */
public class Demo02 {
    //多重catch語(yǔ)句
    public static void main(String[] args) {
        //定義一個(gè)緩沖流對(duì)象,以后在IO流階段壹哥會(huì)細(xì)講
        BufferedReader reader = null;
        try {
            //對(duì)接一個(gè)file.txt文件,該文件可能不存在
            reader = new BufferedReader(new FileReader("file.txt"));
            //讀取文件中的內(nèi)容。所有的IO流都可能會(huì)產(chǎn)生IO流異常
            String line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
        } catch (FileNotFoundException e) {
        	//處理文件不存在時(shí)的異常
            System.out.println("文件不存在:" + e.getMessage());
        } catch (IOException e) {
        	//處理IO異常
            System.out.println("讀取文件失敗:" + e.getMessage());
        } 
	}
}

在這段代碼中,我們嘗試打開(kāi)一個(gè)名為file.txt的文件,并逐行讀取其內(nèi)容。如果該文件不存在或讀取失敗,程序?qū)?huì)在相應(yīng)的catch塊中處理異常,并打印出異常消息。具體地來(lái)說(shuō),就是try代碼塊的第16行代碼調(diào)用了FileReader的構(gòu)造方法,這里有可能會(huì)發(fā)生FileNotFoundException異常。而第18行調(diào)用BufferedReader輸入流的readLine()方法時(shí),有可能會(huì)發(fā)生IOException異常。

因?yàn)镕ileNotFoundException異常是IOException異常的子類(lèi),所以我們應(yīng)該先捕獲 FileNotFoundException異常,即第23行代碼;后捕獲IOException異常,即第26行代碼。但是如果我們將FileNotFoundException和IOException異常的捕獲順序進(jìn)行調(diào)換,那么捕獲FileNotFoundException異常的代碼塊永遠(yuǎn)也不會(huì)執(zhí)行,所以FileNotFoundException異常也永遠(yuǎn)不會(huì)被處理。當(dāng)然,如果多個(gè)異常之間沒(méi)有父子關(guān)系,則其順序就無(wú)所謂了。

4. try-catch-finally結(jié)構(gòu)

在上面的代碼中,我們涉及到了IO流的相關(guān)內(nèi)容,這一塊我們還沒(méi)有開(kāi)始進(jìn)行學(xué)習(xí),會(huì)在以后給大家進(jìn)行詳細(xì)地講解。

IO流屬于一種比較消耗物理資源的API,使用完之后應(yīng)該把IO流進(jìn)行關(guān)閉,否則就可能會(huì)導(dǎo)致物理資源被過(guò)多的消耗。那么我們?cè)撛谀睦镪P(guān)閉IO流呢?有的人會(huì)說(shuō),我們可以在try語(yǔ)句塊執(zhí)行完正常的功能后關(guān)閉IO流。但是大家要知道,try語(yǔ)句塊和catch語(yǔ)句塊有可能因?yàn)楫惓2](méi)有被完全執(zhí)行,那么try里打開(kāi)的這些物理資源到底要在哪里回收呢?

為了確保這些物理資源一定可以被回收,異常處理機(jī)制給我們提供了finally代碼塊,且Java 7之后又提供了自動(dòng)資源管理(Automatic Resource Management)技術(shù),更是可以?xún)?yōu)雅地解決資源回收的問(wèn)題。

4.1 基本語(yǔ)法

無(wú)論是否發(fā)生異常,finally里的代碼總會(huì)被執(zhí)行。在 finally代碼塊中,我們可以執(zhí)行一些清理等收尾善后性質(zhì)的代碼,其基本語(yǔ)法格式如下:

try {
    // 可能會(huì)發(fā)生異常的語(yǔ)句
} catch(ExceptionType e) {
    // 處理異常語(yǔ)句
} finally {
    // 執(zhí)行清理代碼塊,這里的代碼肯定會(huì)被執(zhí)行到,除非極特殊的情況發(fā)生
}

上面的代碼中,無(wú)論是否發(fā)生了異常(除極特殊的情況外,比如提前調(diào)用了System.exit()退出虛擬機(jī)的方法),finally語(yǔ)句塊中的代碼都會(huì)被執(zhí)行。另外,finally語(yǔ)句也可以直接和try語(yǔ)句配合使用,其語(yǔ)法格式如下:

try {
    // 邏輯代碼塊
} finally {
    // 清理代碼塊
}

我們?cè)谑褂胻ry-catch-finally語(yǔ)句時(shí)要注意以下幾點(diǎn):

在異常處理的語(yǔ)法結(jié)構(gòu)中,只有try是必需的。如果沒(méi)有try代碼塊,則不能有后面的catch和finally;

雖然catch塊和finally塊是可選的,但也不能只有try塊,catch塊和finally塊至少要出現(xiàn)其中之一,也可以同時(shí)出現(xiàn);

可以有多個(gè)catch塊,捕獲父類(lèi)異常的catch塊,必須位于捕獲子類(lèi)異常的后面;

多個(gè)catch塊必須位于try塊之后,finally塊必須位于所有的catch塊之后;

只有finally與try語(yǔ)句塊的語(yǔ)法格式,這種情況會(huì)導(dǎo)致異常的丟失,所以并不常見(jiàn);

通常情況下,我們不應(yīng)該在finally代碼塊中使用return或throw等會(huì)導(dǎo)致方法終止的語(yǔ)句,否則這將會(huì)導(dǎo)致try和catch代碼塊中的return和throw語(yǔ)句失效。

尤其是try-catch-finally與return的結(jié)合,是我們面試時(shí)的一個(gè)考點(diǎn)哦。有些面試官會(huì)賤賤地問(wèn)你try-catch-finally中如果有return,會(huì)發(fā)生什么,請(qǐng)大家自行做個(gè)實(shí)驗(yàn)吧。

4.2 代碼實(shí)現(xiàn)

接下來(lái)在之前的案例基礎(chǔ)上進(jìn)行改造,引入finally代碼塊:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
 * @author 
 */
public class Demo03 {
    //try-catch-finally語(yǔ)句
    public static void main(String[] args) {
        //定義一個(gè)緩沖流對(duì)象,以后在IO流階段壹哥會(huì)細(xì)講
        BufferedReader reader = null;
        try {
        	//對(duì)接一個(gè)file.txt文件,該文件可能不存在
            reader = new BufferedReader(new FileReader("file.txt"));
            //讀取文件中的內(nèi)容。所有的IO流都可能會(huì)產(chǎn)生IO流異常
            String line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
        } catch (FileNotFoundException e) {
        	//處理文件不存在時(shí)的異常
            System.out.println("文件不存在:" + e.getMessage());
        } catch (IOException e) {
            //處理IO異常
            System.out.println("讀取文件失?。? + e.getMessage());
        } finally {
            try {
                //在finally代碼塊中也可以進(jìn)行try-catch的操作
                if (reader != null) {
                	//關(guān)閉IO流
                    reader.close();
                }
            } catch (IOException e) {
                System.out.println("關(guān)閉文件失?。? + e.getMessage());
            }
        }
	}
}

在這段代碼中,我們嘗試打開(kāi)一個(gè)名為file.txt的文件,并逐行讀取其內(nèi)容。如果文件不存在或讀取失敗,程序?qū)⒃谙鄳?yīng)的catch塊中處理異常,并打印出異常消息。無(wú)論是否發(fā)生異常,程序都會(huì)在finally塊中關(guān)閉文件。

4.3 小結(jié)

在try-catch-finally組合的結(jié)構(gòu)中,其執(zhí)行流程如下圖所示:

根據(jù)該流程可知,try-catch-finally語(yǔ)句塊的執(zhí)行情況可以細(xì)分為以下幾種情況:

如果try代碼塊中沒(méi)有拋出異常,則執(zhí)行完try代碼塊后會(huì)直接執(zhí)行finally代碼塊;

如果try代碼塊中拋出了異常,并被catch子句捕捉,則終止try代碼塊的執(zhí)行,轉(zhuǎn)而執(zhí)行相匹配的 catch代碼塊,之后再執(zhí)行 finally代碼塊;

如果try代碼塊中拋出的異常沒(méi)有被任何catch子句捕獲到,將會(huì)直接執(zhí)行finally代碼塊中的語(yǔ)句,并把該異常傳遞給該方法的調(diào)用者;

如果在finally代碼塊中也拋出了異常,則會(huì)把該異常傳遞給該方法的調(diào)用者。

二. 結(jié)語(yǔ)

至此,就把今天的內(nèi)容講解完畢了,通過(guò)今天的內(nèi)容,大家要注意以下幾點(diǎn):

  • try...catch與if...else是不一樣的,try后面的花括號(hào){ }不可以省略,即便try中只有一行代碼;
  • 同樣的,catch的花括號(hào) { } 也不可以省略;
  • 當(dāng)捕獲的多個(gè)異常類(lèi)之間存在父子關(guān)系時(shí),一般是先捕獲子類(lèi),再捕獲父類(lèi);
  • 在異常處理的語(yǔ)法結(jié)構(gòu)中,只有try是必需的。如果沒(méi)有try代碼塊,則不能有后面的catch和finally。

以上就是學(xué)習(xí)Java之異常到底該如何捕獲和處理的詳細(xì)內(nèi)容,更多關(guān)于Java異常捕獲和處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • String?concat(String?str)使用小結(jié)

    String?concat(String?str)使用小結(jié)

    這篇文章主要介紹了String?concat(String?str)使用小結(jié),在了解concat()之前,首先需要明確的是String的兩點(diǎn)特殊性,一是長(zhǎng)度不可變二是值不可變,本文給大家詳細(xì)講解,需要的朋友可以參考下
    2022-11-11
  • Java+opencv3.2.0之直方圖均衡詳解

    Java+opencv3.2.0之直方圖均衡詳解

    這篇文章主要為大家詳細(xì)介紹了Java+opencv3.2.0之直方圖均衡的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • springboot分布式整合dubbo的方式

    springboot分布式整合dubbo的方式

    Dubbo是一款高性能、輕量級(jí)的開(kāi)源Java RPC框架,本文通過(guò)實(shí)例代碼給大家介紹springboot分布式整合dubbo的方式,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • Java JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)(Run-Time Data Areas)

    Java JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)(Run-Time Data Areas)

    運(yùn)行時(shí)數(shù)據(jù)區(qū),是java虛擬機(jī)定義的在程序執(zhí)行期間使用的各種運(yùn)行時(shí)的數(shù)據(jù)區(qū),通過(guò)JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)圖例給大家展示的很詳細(xì),對(duì)JVM 運(yùn)行時(shí)數(shù)據(jù)區(qū)相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • SpringBoot使用hutool-captcha實(shí)現(xiàn)驗(yàn)證碼生成與驗(yàn)證

    SpringBoot使用hutool-captcha實(shí)現(xiàn)驗(yàn)證碼生成與驗(yàn)證

    在springboot的登陸頁(yè)面中為了防止機(jī)器大規(guī)模注冊(cè),機(jī)器暴力破解數(shù)據(jù)密碼等危害,需要驗(yàn)證隨機(jī)生成的驗(yàn)證碼,本文主要介紹了SpringBoot使用hutool-captcha實(shí)現(xiàn)驗(yàn)證碼生成與驗(yàn)證,感興趣的可以了解一下
    2023-12-12
  • Java文件過(guò)濾器實(shí)現(xiàn)按條件篩選文件

    Java文件過(guò)濾器實(shí)現(xiàn)按條件篩選文件

    本文主要介紹了Java文件過(guò)濾器實(shí)現(xiàn)按條件篩選文件,文件過(guò)濾器是在文件處理中起到重要作用的工具,它可以用來(lái)篩選文件并根據(jù)特定的條件進(jìn)行過(guò)濾,下面就來(lái)介紹一下
    2024-04-04
  • 消息隊(duì)列MQ使用詳解

    消息隊(duì)列MQ使用詳解

    消息隊(duì)列(MQ)是一種基于“先進(jìn)先出”原則的數(shù)據(jù)結(jié)構(gòu),廣泛應(yīng)用于分布式系統(tǒng)中,主要用于應(yīng)用解耦、異步消息處理和流量削峰,消息隊(duì)列中間件通過(guò)允許生產(chǎn)者發(fā)送消息到隊(duì)列,消費(fèi)者從隊(duì)列中拉取消息或訂閱消息,實(shí)現(xiàn)高效、可擴(kuò)展和最終一致性的系統(tǒng)架構(gòu)
    2024-10-10
  • 最新評(píng)論