最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java常見(jiàn)異常及處理方式總結(jié)

 更新時(shí)間:2021年06月10日 09:00:27   作者:南方有喬木  
今天給大家?guī)?lái)的是Java的相關(guān)知識(shí),文章圍繞著Java異常展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下

一、概述

異常指不期而至的各種狀況,它在程序運(yùn)行的過(guò)程中發(fā)生。作為開(kāi)發(fā)者,我們都希望自己寫(xiě)的代碼 永遠(yuǎn)都不會(huì)出現(xiàn) bug,然而現(xiàn)實(shí)告訴我們并沒(méi)有這樣的情景。如果用戶在程序的使用過(guò)程中因?yàn)橐恍┰蛟斐伤臄?shù)據(jù)丟失,這個(gè)用戶就可能不會(huì)再使用該程序了。所以,對(duì)于程序的錯(cuò)誤以及外部環(huán)境能夠?qū)τ脩粼斐傻挠绊?,我們?yīng)當(dāng)及時(shí)報(bào)告并且以適當(dāng)?shù)姆绞絹?lái)處理這個(gè)錯(cuò)誤。

之所以要處理異常,也是為了增強(qiáng)程序的魯棒性。

異常都是從 Throwable 類派生出來(lái)的,而 Throwable 類是直接從 Object 類繼承而來(lái)。你可以在 Java SE 官方 API 文檔中獲取更多關(guān)于它們的知識(shí)。

二、異常分類

異常通常有四類:

  • Error:系統(tǒng)內(nèi)部錯(cuò)誤,這類錯(cuò)誤由系統(tǒng)進(jìn)行處理,程序本身無(wú)需捕獲處理。
  • Exception:可以處理的異常。
  • RuntimeException:可以捕獲,也可以不捕獲的異常。
  • 繼承 Exception 的其他類:必須捕獲,通常在 API 文檔中會(huì)說(shuō)明這些方法拋出哪些異常。

平時(shí)主要關(guān)注的異常是 Exception 下的異常,而 Exception 異常下又主要分為兩大類異常,一個(gè)是派生于 RuntimeExcption 的異常,一個(gè)是除了 RuntimeExcption 體系之外的其他異常。

RuntimeExcption 異常(運(yùn)行時(shí)異常)通常有以下幾種:

  • 錯(cuò)誤的類型轉(zhuǎn)換
  • 數(shù)組訪問(wèn)越界
  • 訪問(wèn) null 指針
  • 算術(shù)異常

一般來(lái)說(shuō),RuntimeException 都是代碼邏輯出現(xiàn)問(wèn)題。

非 RuntimeException(受檢異常,Checked Exception)一般有:

  • 打開(kāi)一個(gè)不存在的文件
  • 沒(méi)有找到具有指定名稱的類
  • 操作文件異常

受檢異常是編譯器要求必須處理的異常,必須使用 try catch 處理,或者使用 throw 拋出,交給上層調(diào)用者處理。

三、聲明及拋出

 throw 拋出異常

當(dāng)程序運(yùn)行時(shí)數(shù)據(jù)出現(xiàn)錯(cuò)誤或者我們不希望發(fā)生的情況出現(xiàn)的話,可以通過(guò)拋出異常來(lái)處理。

異常拋出語(yǔ)法:

throw new 異常類();

新建 ThrowTest.java:

public class ThrowTest {
 
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = null;
        //當(dāng)a或者b為null時(shí),拋出異常
        if (a == null || b == null) {
            throw new NullPointerException();
        } else {
            System.out.println(a + b);
        }
    }
}

運(yùn)行:

Exception in thread "main" java.lang.NullPointerException
    at ThrowTest.main(ThrowTest.java:8)

throws 聲明異常

throws 用于聲明異常,表示該方法可能會(huì)拋出的異常。如果聲明的異常中包括 checked 異常(受檢異常),那么調(diào)用者必須捕獲處理該異?;蛘呤褂?throws 繼續(xù)向上拋出。throws 位于方法體前,多個(gè)異常之間使用 , 分割。

新建ThrowsTest.java:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
 
public class ThrowsTest {
 
    public static void main(String[] args) throws FileNotFoundException {
        //由方法的調(diào)用者捕獲異?;蛘呃^續(xù)向上拋出
        throwsTest();
 
    }
 
    public static void throwsTest() throws FileNotFoundException {
        new FileInputStream("/home/project/shiyanlou.file");
    }
}

編譯運(yùn)行:

Exception in thread "main" java.io.FileNotFoundException: /home/project/shiyanlou.file (系統(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 ThrowsTest.throwsTest(ThrowsTest.java:13)
    at ThrowsTest.main(ThrowsTest.java:8)

四、捕獲異常

通常拋出異常后,還需要將異常捕獲。使用 try 和 catch 語(yǔ)句塊來(lái)捕獲異常,有時(shí)候還會(huì)用到 finally。

對(duì)于上述三個(gè)關(guān)鍵詞所構(gòu)成的語(yǔ)句塊,try 語(yǔ)句塊是必不可少的,catch 和 finally 語(yǔ)句塊可以根據(jù)情況選擇其一或者全選。你可以把可能發(fā)生錯(cuò)誤或出現(xiàn)問(wèn)題的語(yǔ)句放到 try 語(yǔ)句塊中,將異常發(fā)生后要執(zhí)行的語(yǔ)句放到 catch 語(yǔ)句塊中,而 finally 語(yǔ)句塊里面放置的語(yǔ)句,不管異常是否發(fā)生,它們都會(huì)被執(zhí)行。

你可能想說(shuō),那我把所有有關(guān)的代碼都放到 try 語(yǔ)句塊中不就妥當(dāng)了嗎?可是你需要知道,捕獲異常對(duì)于系統(tǒng)而言,其開(kāi)銷非常大,所以應(yīng)盡量減少該語(yǔ)句塊中放置的語(yǔ)句。

新建 CatchException.java:

public class CatchException {
    public static void main(String[] args) {
        try {
            // 下面定義了一個(gè)try語(yǔ)句塊
 
            System.out.println("I am try block.");
 
            Class<?> tempClass = Class.forName("");
            // 聲明一個(gè)空的Class對(duì)象用于引發(fā)“類未發(fā)現(xiàn)異常”
            System.out.println("Bye! Try block.");
 
        } catch (ClassNotFoundException e) {
            // 下面定義了一個(gè)catch語(yǔ)句塊
            System.out.println("I am catch block.");
 
            e.printStackTrace();
            //printStackTrace()的意義在于在命令行打印異常信息在程序中出錯(cuò)的位置及原因
 
            System.out.println("Goodbye! Catch block.");
 
        } finally {
            // 下面定義了一個(gè)finally語(yǔ)句塊
            System.out.println("I am finally block.");
        }
    }
}

編譯運(yùn)行:

I am try block.
I am catch block.
java.lang.ClassNotFoundException:
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at CatchException.main(CatchException.java:8)
Goodbye! Catch block.
I am finally block.

五、捕獲多個(gè)異常

在一段代碼中,可能會(huì)由于各種原因拋出多種不同的異常,而對(duì)于不同的異常,我們希望用不同的方式來(lái)處理它們,而不是籠統(tǒng)的使用同一個(gè)方式處理,在這種情況下,可以使用異常匹配,當(dāng)匹配到對(duì)應(yīng)的異常后,后面的異常將不再進(jìn)行匹配。

新建源代碼文件 MultipleCapturesDemo.java:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
 
public class MultipleCapturesDemo {
    public static void main(String[] args) {
        try {
            new FileInputStream("");
        } catch (FileNotFoundException e) {
            System.out.println("IO 異常");
        } catch (Exception e) {
            System.out.println("發(fā)生異常");
        }
    }
}

編譯運(yùn)行:

IO 異常

在處理異常時(shí),并不要求拋出的異常同 catch 所聲明的異常完全匹配,子類的對(duì)象也可以匹配父類的處理程序。比如異常 A 繼承于異常 B,那么在處理多個(gè)異常時(shí),一定要將異常 A 放在異常 B 之前捕獲,如果將異常 B 放在異常 A 之前,那么將永遠(yuǎn)匹配到異常 B,異常 A 將永遠(yuǎn)不可能執(zhí)行,并且編譯器將會(huì)報(bào)錯(cuò)。

六、自定義異常

盡管 Java SE 的 API 已經(jīng)為我們提供了數(shù)十種異常類,然而在實(shí)際的開(kāi)發(fā)過(guò)程中,你仍然可能遇到未知的異常情況。此時(shí),你就需要對(duì)異常類進(jìn)行自定義。

自定義一個(gè)異常類非常簡(jiǎn)單,只需要讓它繼承 Exception 或其子類就行。在自定義異常類的時(shí)候,建議同時(shí)提供無(wú)參構(gòu)造方法和帶字符串參數(shù)的構(gòu)造方法,后者可以為你在調(diào)試時(shí)提供更加詳細(xì)的信息。

百聞不如一見(jiàn),下面我們嘗試自定義一個(gè)算術(shù)異常類。

創(chuàng)建一個(gè) MyAriException 類:

主要的代碼如下:

// MyAriException.java
public class MyAriException extends ArithmeticException {
    //自定義異常類,該類繼承自ArithmeticException
 
    public MyAriException() {
 
    }
    //實(shí)現(xiàn)默認(rèn)的無(wú)參構(gòu)造方法
 
    public MyAriException(String msg) {
        super(msg);
    }
    //實(shí)現(xiàn)可以自定義輸出信息的構(gòu)造方法,將待輸出信息作為參數(shù)傳入即可
}

添加一個(gè) ExceptionTest 類作為測(cè)試用,在該類的 main() 方法中,可以嘗試使用 throw 拋出自定義的異常。

代碼片段如下:

// ExceptionTest.java
import java.util.Arrays;
 
public class ExceptionTest {
    public static void main(String[] args) {
        int[] array = new int[5];
        //聲明一個(gè)長(zhǎng)度為5的數(shù)組
 
        Arrays.fill(array, 5);
        //將數(shù)組中的所有元素賦值為5
 
        for (int i = 4; i > -1; i--) {
            //使用for循環(huán)逆序遍歷整個(gè)數(shù)組,i每次遞減
 
            if (i == 0) {
            // 如果i除以了0,就使用帶異常信息的構(gòu)造方法拋出異常
 
                throw new MyAriException("There is an exception occured.");
            }
 
            System.out.println("array[" + i + "] / " + i + " = " + array[i] / i);
            // 如果i沒(méi)有除以0,就輸出此結(jié)果
        }
    }
}

檢查一下代碼,編譯并運(yùn)行,期待中的自定義錯(cuò)誤信息就展現(xiàn)在控制臺(tái)中了:

array[4] / 4 = 1
array[3] / 3 = 1
array[2] / 2 = 2
array[1] / 1 = 5
Exception in thread "main" MyAriException: There is an exception occured.
    at ExceptionTest.main(ExceptionTest.java:17)

七、異常堆棧

當(dāng)異常拋出后,我們可以通過(guò)異常堆棧追蹤程序的運(yùn)行軌跡,以便我們更好的 DEBUG。

新建一個(gè) ExceptionStackTrace.java:

public class ExceptionStackTrace {
    private static void method1() {
        method2();
    }
 
    private static void method2() {
        throw new NullPointerException();
    }
    public static void main(String[] args) {
        try {
            method1();
        } catch (Exception e) {
            //打印堆棧軌跡
            e.printStackTrace();
        }
    }
}

編譯運(yùn)行:

java.lang.NullPointerException
    at ExceptionStackTrace.method2(ExceptionStackTrace.java:7)
    at ExceptionStackTrace.method1(ExceptionStackTrace.java:3)
    at ExceptionStackTrace.main(ExceptionStackTrace.java:11)

通過(guò)上面的異常堆棧軌跡,在對(duì)比我們方法的調(diào)用過(guò)程,可以得出異常信息中首先打印的是距離拋出異常最近的語(yǔ)句,接著是調(diào)用該方法的方法,一直到最開(kāi)始被調(diào)用的方法。從下往上看,就可以得出程序運(yùn)行的軌跡

到此這篇關(guān)于Java常見(jiàn)異常及處理方式總結(jié)的文章就介紹到這了,更多相關(guān)Java異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中利用BitMap位圖實(shí)現(xiàn)海量級(jí)數(shù)據(jù)去重

    Java中利用BitMap位圖實(shí)現(xiàn)海量級(jí)數(shù)據(jù)去重

    有許多方法可以用來(lái)去重,比如使用列表、集合等等,但這些方法通常只適用于一般情況,然而,當(dāng)涉及到大量數(shù)據(jù)去重時(shí),常見(jiàn)的 Java Set、List,甚至是 Java 8 的新特性 Stream 流等方式就顯得不太合適了,本文給大家介紹了Java中利用BitMap位圖實(shí)現(xiàn)海量級(jí)數(shù)據(jù)去重
    2024-04-04
  • 淺談Java由于不當(dāng)?shù)膱?zhí)行順序?qū)е碌乃梨i

    淺談Java由于不當(dāng)?shù)膱?zhí)行順序?qū)е碌乃梨i

    為了保證線程的安全,我們引入了加鎖機(jī)制,但是如果不加限制的使用加鎖,就有可能會(huì)導(dǎo)致順序死鎖(Lock-Ordering Deadlock)。本文將會(huì)討論一下順序死鎖的問(wèn)題。
    2021-06-06
  • java使用命令行打包JAR

    java使用命令行打包JAR

    如何把寫(xiě)好的Java程序打包為jar文件呢?下面說(shuō)的就是java使用命令行打包JAR的方法
    2013-11-11
  • springboot使用@value注入配置失敗的解決

    springboot使用@value注入配置失敗的解決

    這篇文章主要介紹了springboot使用@value注入配置失敗的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • javaweb上傳下載實(shí)例完整版解析(上)

    javaweb上傳下載實(shí)例完整版解析(上)

    這篇文章主要為大家詳細(xì)解析了javaweb上傳下載實(shí)例,本文重點(diǎn)在于文件上傳功能的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • mybatis注解之@Mapper和@MapperScan的使用

    mybatis注解之@Mapper和@MapperScan的使用

    這篇文章主要介紹了mybatis注解之@Mapper和@MapperScan的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • @Async異步線程池以及線程的命名方式

    @Async異步線程池以及線程的命名方式

    這篇文章主要介紹了@Async異步線程池以及線程的命名方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java基礎(chǔ)之簡(jiǎn)單介紹一下Maven

    Java基礎(chǔ)之簡(jiǎn)單介紹一下Maven

    今天給大家復(fù)習(xí)一下Java基礎(chǔ)知識(shí),簡(jiǎn)單介紹Maven,文中有非常詳細(xì)的解釋,對(duì)Java初學(xué)者很有幫助喲,需要的朋友可以參考下
    2021-05-05
  • java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實(shí)例

    java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實(shí)例

    這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 淺談SpringBoot集成Redis實(shí)現(xiàn)緩存處理(Spring AOP實(shí)現(xiàn))

    淺談SpringBoot集成Redis實(shí)現(xiàn)緩存處理(Spring AOP實(shí)現(xiàn))

    這篇文章主要介紹了淺談SpringBoot集成Redis實(shí)現(xiàn)緩存處理(Spring AOP實(shí)現(xiàn)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12

最新評(píng)論

平武县| 桂东县| 谷城县| 滦南县| 河东区| 永兴县| 自贡市| 怀宁县| 兴和县| 公主岭市| 固始县| 新昌县| 竹北市| 四平市| 巴彦淖尔市| 东丽区| 榆中县| 河北区| 萝北县| 郁南县| 昌图县| 鄱阳县| 凌海市| 喜德县| 温宿县| 常山县| 莆田市| 海南省| 沙坪坝区| 涞水县| 甘泉县| 和硕县| 信宜市| 湘西| 阳朔县| 朝阳区| 健康| 萍乡市| 丹东市| 永嘉县| 桃园市|