成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 異常實(shí)戰(zhàn)

libxd / 3425人閱讀

摘要:不過按照經(jīng)驗(yàn)來說,這類異常要么盡量避免,要么出現(xiàn)了就要做異常處理,從而保證程序的健壯性。業(yè)務(wù)是千變?nèi)f化,但是它們可能產(chǎn)生的異常處理方式是不會變化的,按照這個(gè)思路去做異常處理即可。

前言:說到異常體系,可能對于一些初入職場的老鐵會很頭痛,不能夠很清晰的描述異常是個(gè)什么情況。那么本文將通過打流水仗的方式給大家介紹一下工作中涉及的異常知識。首先能看到本文,說明也對異常是有了解的,所以文章開頭就通過一些概念和小例子快速熟悉一下異常,緊接著介紹異常體系,對于理解整個(gè)異常體系架構(gòu)非常有幫助,最后介紹了非常非常重要的自定義異常,學(xué)會了這些,在工作中遇到的常見異常問題,處理起來一定都會游刃有余啦。
異常概述 異常

異常就是在程序的運(yùn)行過程中所發(fā)生的不正常的事件,它會中斷正在運(yùn)行的程序

異常處理

Java 編程語言使用異常處理機(jī)制為程序提供了錯(cuò)誤處理的能力,好處就是:如果代碼中存在了異常,但是進(jìn)行了捕獲處理,那么程序就會繼續(xù)運(yùn)行下去,不會因?yàn)橐粋€(gè)異常導(dǎo)致程序中斷運(yùn)行。

例子1:如果程序可能存在異常但是沒有做異常處理,那么將會導(dǎo)致程序不能正常的運(yùn)行下去:

public class ExceptionTest {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int c = a / b;
        System.out.println(c);
        System.out.println("輸出了本句話嗎");
    }
}

輸出結(jié)果是:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at cn.caijiajia.cn.caijiajia.exception.ExceptionTest.main(ExceptionTest.java:12)

例子2:如果程序可能存在異常并做了異常處理,那么程序就會正常的運(yùn)行下去:

public class ExceptionTest {
    public static void main(String[] args) {
        try {
            int a = 10;
            int b = 0;
            int c = a / b;
            System.out.println(c);
            System.out.println("異常代碼下面的代碼將都不會執(zhí)行");
        } catch (ArithmeticException e) {
            System.out.println("處理異常的代碼");
        }
        System.out.println("異常處理代碼下面的程序?qū)^續(xù)執(zhí)行而不會程序中斷");
    }
}

輸出結(jié)果是:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at cn.caijiajia.cn.caijiajia.exception.ExceptionTest.main(ExceptionTest.java:12)
處理異常的代碼
異常處理代碼下面的程序?qū)^續(xù)執(zhí)行而不會程序中斷
    
Java 中如何處理異常 異常處理的 5 個(gè)關(guān)鍵字

try:執(zhí)行可能產(chǎn)生異常的代碼
catch:捕獲異常并對異常情況做相應(yīng)處理
finally:無論是否發(fā)生異常,代碼總能執(zhí)行。(釋放資源,關(guān)閉數(shù)據(jù)庫連接)
throws:聲明可能拋出的各種異常(受檢異常較多)
throw:手動(dòng)的拋出異常(手動(dòng)拋出我們自定義的異常較多)

異常處理后程序運(yùn)行情況

情況一:沒產(chǎn)生異常

public void method() {
    try {
        // 代碼段① [正常業(yè)務(wù)邏輯代碼,此處不會產(chǎn)生異常]
    } catch (Exception e) {
        // 代碼段② [對異常處理的代碼段]
    }
    // 代碼段③ [正常業(yè)務(wù)邏輯代碼]
}

運(yùn)行結(jié)果:
    代碼段①
    代碼段③

情況二:產(chǎn)生異常并捕獲異常

public void method() {
    try {
        // 異常代碼段① [正常業(yè)務(wù)邏輯代碼,此處會產(chǎn)生異常]
        // 代碼段② [正常業(yè)務(wù)邏輯代碼]
    } catch (Exception e) {
        // 代碼段③ [對異常處理的代碼段]
    }
    // 代碼段④ [正常業(yè)務(wù)邏輯代碼]
}

運(yùn)行結(jié)果:
    代碼段①
    代碼段③   
    代碼段④

注意:如果想要正常的 代碼段② 執(zhí)行,那么可以把代碼段從 trycatch 里面提出來,和 代碼段④ 放在一起,當(dāng)異常處理完之后,就可以同時(shí)去執(zhí)行 代碼段② 和 代碼段④ 了。
    

情況三:產(chǎn)生異常并捕獲異常,但是捕獲異常類型不匹配產(chǎn)生異常類型

public void method() {
    try {
        // 異常代碼段① [正常業(yè)務(wù)邏輯代碼,此處會產(chǎn)生角標(biāo)越界異常]
        // 代碼段② [正常業(yè)務(wù)邏輯代碼]
    } catch (IOException e) {
        // 代碼段③ [對異常處理的代碼段]
    }
    // 代碼段④ [正常業(yè)務(wù)邏輯代碼]
}

運(yùn)行結(jié)果:
    代碼段①
    
注意:如果捕獲異常類型和產(chǎn)生的異常類型不匹配,那么就和沒有處理異常情況一樣了,trycatch 后面的代碼段將都不會執(zhí)行,發(fā)生異常就會導(dǎo)致程序中斷運(yùn)行
異常體系 異常類層次圖

Error 和 Exception

Error 類和 Exception 類的父類都是 Throwable 類

Error 類一般是指與虛擬機(jī)相關(guān)的問題,如系統(tǒng)崩潰,虛擬機(jī)錯(cuò)誤,內(nèi)存空間不足,方法調(diào)用棧溢等。對于這類錯(cuò)誤的導(dǎo)致的應(yīng)用程序中斷,僅靠程序本身無法恢復(fù)和和預(yù)防,遇到這樣的錯(cuò)誤,建議讓程序終止。因此我們在學(xué)習(xí)的時(shí)候主要是學(xué)會 Exception。

Exception 類表示程序可以處理的異常,可以捕獲且可能恢復(fù)。遇到這類異常,應(yīng)該盡可能處理異常,使程序恢復(fù)運(yùn)行,而不應(yīng)該隨意終止異常。

Exception 異常分類及處理

Exception 異常主要分為兩大類:Checked Exception,Unchecked Exception;即受檢異常和非受檢異常(運(yùn)行時(shí)異常)

Checked Exception:受檢異常,即 Java 程序必須顯式處理的異常,如果程序沒有處理 Checked 異常,該程序在編譯時(shí)就會發(fā)生錯(cuò)誤無法編譯。例如圖中所示的 IOException

處理受檢異常通過有如下兩種方式:
方式一:通過 trycatch 顯式處理異常,否則編譯不通過

public class ExceptionTest {
    public static void main(String[] args) {
        try {
            // 通過 trycatch 顯示處理異常
            FileInputStream fis = new FileInputStream(new File(""));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方式二:通過 throws 拋出異常,讓上層來處理異常,否則編譯不通過

public class ExceptionTest {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(new File(""));
    }
}

Unchecked Exception:非受檢異常,即 RuntimeException 運(yùn)行時(shí)異常。這些異常程序可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯(cuò)誤引起的,程序應(yīng)該從邏輯角度盡可能避免這類異常的發(fā)生。比如常見的 NullPointerException、IndexOutOfBoundsException 就是運(yùn)行時(shí)異常。不過按照經(jīng)驗(yàn)來說,這類異常要么盡量避免,要么出現(xiàn)了就要做異常處理,從而保證程序的健壯性。

處理運(yùn)行時(shí)異常通過有如下兩種方式:
方式一:常見的空指針處理

// 通過寫偽代碼來演示其處理流程
if (對象 == null) {
    // 處理對象為 null 的邏輯
} else {
    // 處理對象不為 null 的邏輯
}

方式二:跟業(yè)務(wù)相關(guān)異常,拋出自定義異常

// 通過手機(jī)號注冊業(yè)務(wù)邏輯
User user = dao.getByPhone(phone);
if (user != null) {
    // 說明此手機(jī)號碼已經(jīng)被注冊,那么就拋出業(yè)務(wù)異常(即自定義異常)
    throw new MyRuntimeException("改用戶已注冊");
}
// 如果沒有注冊,繼續(xù)走注冊流程代碼

總結(jié):通過本小節(jié)異常分類及處理可以發(fā)現(xiàn),受檢異常處理起來很簡單,因?yàn)槌绦蛉绻蛔鲲@式處理,那么就會編譯不通過,強(qiáng)制要求處理;而運(yùn)行時(shí)異常則是看心情處理的,但是如果想要公司代碼更加健壯,更少的出現(xiàn)問題,最好要做一下異常處理;但是如果做這個(gè)處理呢?對于這種運(yùn)行時(shí)異常,大部分都是和業(yè)務(wù)相關(guān)的,比如手機(jī)號注冊例子;這種情況下在 Java 的異常體系中并沒有相關(guān)異常類做處理,因?yàn)?Java 不管在智能,也不可能知道我們的業(yè)務(wù)情況,當(dāng)然就不會針對業(yè)務(wù)提供一些異常類供我們使用,因此為了解決這個(gè)問題,自定義異常就出現(xiàn)了,它對于我們處理業(yè)務(wù)中產(chǎn)生的運(yùn)行時(shí)異常非常非常重要,接下來就來學(xué)習(xí)自定義異常。

自定義異常 產(chǎn)生原因

Java 現(xiàn)有的異常類不能滿足更多的業(yè)務(wù)異常處理,因此我們要自定義合適的異常類來處理業(yè)務(wù)異常。

如何自定義異常類

第一步:聲明一個(gè)類繼承 Exception 或其子類

那么我們聲明的這個(gè)類到底繼承誰呢?Exception?RuntimeException?
答案是:RuntimeException
原因是:看了上面的異常類層次圖,應(yīng)該也能發(fā)現(xiàn),Exception 下面有兩大類子類,受檢異常和運(yùn)行時(shí)異常,如果我們自定義的類繼承了 Exception,則就會因?yàn)槭軝z異常的存在而變成了受檢異常類,這個(gè)時(shí)候我們自定義的異常類,如果在程序中使用,那么就必須顯式處理異常,要么 trycatch,要么拋出給上層;這樣一來,使得我們的程序很混亂,而且并沒有達(dá)到我們預(yù)期的結(jié)果。然后當(dāng)我們自定義的類繼承了 RuntimeException 之后,當(dāng)我們程序中想要使用的時(shí)候,直接 new 一個(gè)即可,而不再需要顯式去再多做處理了。

第二步:自定義異常類應(yīng)至少包含四個(gè)構(gòu)造方法

public class MyException extends RuntimeException {
    public MyException() {}

    public MyException(String msg) {
        super(msg);
    }

    public MyException(Throwable throwable) {
        super(throwable);
    }

    public MyException(String msg, Throwable throwable) {
        super(msg, throwable);
    }
}

第三步:在程序中使用我們的自定義異常

public void testException() {
    User user = dao.getByPhone(phone);
    if (user != null) {
        // 因?yàn)?MyException 是繼承 RuntimeException,所以這里直接拋出異常而不用做其它處理
        throw new MyException("該手機(jī)號已被注冊");
    }
    // ...
} 

注:沒錯(cuò),這里又使用了這個(gè)手機(jī)號注冊的例子,因?yàn)檫@個(gè)就是實(shí)實(shí)在在的在業(yè)務(wù)中的異常處理。業(yè)務(wù)是千變?nèi)f化,但是它們可能產(chǎn)生的異常處理方式是不會變化的,按照這個(gè)思路去做異常處理即可。

tips:如上自定義的異常類中的構(gòu)造方法是最基本的幾個(gè)。每家公司的自定義異??赡芏紩袇^(qū)別,比如定義一個(gè) SuperException 類實(shí)現(xiàn)了 RuntimeException,然后在自定義 ClientException,ServerException 再去繼承 SuperException;那么這就是一套自定義體系了,分為客戶端異常和服務(wù)端異常,在需要做異常處理的地方使用對應(yīng)的異常類并拋出異常錯(cuò)誤信息即可了。再比如可能有的公司會在自定義異常類中在定義一些字段,code,msg 等,來代表某些業(yè)務(wù)碼和對應(yīng)的錯(cuò)誤信息等。不管怎么樣,我們只要了解自定義異常的原理后,面對哪個(gè)公司的自定義異常體系我們都能夠輕松應(yīng)對。

異??偨Y(jié)

通過本文的學(xué)習(xí),一定要掌握兩個(gè)知識,一個(gè)是異常體系,要分清受檢異常和運(yùn)行時(shí)異常;另一個(gè)就是自定義異常,知道如何自定義異常和如何使用自定義異常。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68165.html

相關(guān)文章

  • Spring Boot 2.x 系列教程:WebFlux REST API 全局異常處理 Error

    摘要:挺多人咨詢的,異常處理用切面注解去實(shí)現(xiàn)去全局異常處理。全局異常處理類,代碼如下代碼解析如下抽象類是用來處理全局錯(cuò)誤時(shí)進(jìn)行擴(kuò)展和實(shí)現(xiàn)注解標(biāo)記的切面排序,值越小擁有越高的優(yōu)先級,這里設(shè)置優(yōu)先級偏高。 本文內(nèi)容 為什么要全局異常處理? WebFlux REST 全局異常處理實(shí)戰(zhàn) 小結(jié) 摘錄:只有不斷培養(yǎng)好習(xí)慣,同時(shí)不斷打破壞習(xí)慣,我們的行為舉止才能夠自始至終都是正確的。 一、為什么要全局...

    BicycleWarrior 評論0 收藏0
  • SpringBoot 實(shí)戰(zhàn) (十四) | 統(tǒng)一處理異常

    摘要:前言如題,今天介紹是如何統(tǒng)一處理全局異常的。主要是用于異常攔截出獲取并將設(shè)置到消息類中返回。狀態(tài)碼異常攔截類通過加入來聲明該類可攔截請求,同時(shí)在方法加入并在該注解中指定要攔截的異常類。測試訪問測試正常返回?cái)?shù)據(jù)結(jié)果。 微信公眾號:一個(gè)優(yōu)秀的廢人如有問題或建議,請后臺留言,我會盡力解決你的問題。 前言 如題,今天介紹 SpringBoot 是如何統(tǒng)一處理全局異常的。SpringBoot 中...

    arashicage 評論0 收藏0
  • java 8 實(shí)戰(zhàn)》讀書筆記 -第三章 Lambda表達(dá)式

    摘要:利用前面所述的方法,這個(gè)例子可以用方法引用改寫成下面的樣子構(gòu)造函數(shù)引用對于一個(gè)現(xiàn)有構(gòu)造函數(shù),你可以利用它的名稱和關(guān)鍵字來創(chuàng)建它的一個(gè)引用。 第三章 Lambda表達(dá)式 函數(shù)式接口 函數(shù)式接口就是只定義一個(gè)抽象方法的接口,哪怕有很多默認(rèn)方法,只要接口只定義了一個(gè)抽象方法,它就仍然是一個(gè)函數(shù)式接口。 常用函數(shù)式接口 showImg(https://segmentfault.com/img...

    whinc 評論0 收藏0
  • java 8 實(shí)戰(zhàn)》讀書筆記 -第十三章 函數(shù)式的思考

    摘要:當(dāng)我們希望能界定這二者之間的區(qū)別時(shí),我們將第一種稱為純粹的函數(shù)式編程,后者稱為函數(shù)式編程。函數(shù)式編程我們的準(zhǔn)則是,被稱為函數(shù)式的函數(shù)或方法都只能修改本地變量。另一種觀點(diǎn)支持引用透明的函數(shù)式編程,認(rèn)為方法不應(yīng)該有對外部可見的對象修改。 一、實(shí)現(xiàn)和維護(hù)系統(tǒng) 1.共享的可變數(shù)據(jù) 如果一個(gè)方法既不修改它內(nèi)嵌類的狀態(tài),也不修改其他對象的狀態(tài),使用return返回所有的計(jì)算結(jié)果,那么我們稱其為純粹...

    Donne 評論0 收藏0
  • SpringBoot 實(shí)戰(zhàn) (十) | 聲明式事務(wù)

    摘要:前言如題,今天介紹的聲明式事務(wù)。提供一個(gè)注解在配置類上來開啟聲明式事務(wù)的支持。而在配置里還開啟了對聲明式事務(wù)的支持,代碼如下所以在中,無須顯式開啟使用注解。源碼下載后語以上為聲明式事務(wù)的教程。 微信公眾號:一個(gè)優(yōu)秀的廢人如有問題或建議,請后臺留言,我會盡力解決你的問題。 前言 如題,今天介紹 SpringBoot 的 聲明式事務(wù)。 Spring 的事務(wù)機(jī)制 所有的數(shù)據(jù)訪問技術(shù)都有事務(wù)處...

    ygyooo 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<