chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

JAVA中常見的幾個異常類型及處理方案

454398 ? 來源:阿里云 ? 作者:阿里云原創(chuàng) ? 2020-10-15 16:36 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

異常簡介

先上個圖,看一下常見的幾個異常類型。

所有的異常都來自于Throwable。Throwable有兩個子類,Error和Exception。

Error通常表示的是嚴重錯誤,這些錯誤是不建議被catch的。

注意這里有一個例外,比如ThreadDeath也是繼承自Error,但是它表示的是線程的死亡,雖然不是嚴重的異常,但是因為應用程序通常不會對這種異常進行catch,所以也歸類到Error中。

Exception表示的是應用程序希望catch住的異常。

在Exception中有一個很特別的異常叫做RuntimeException。RuntimeException叫做運行時異常,是不需要被顯示catch住的,所以也叫做unchecked Exception。而其他非RuntimeException的Exception則需要顯示try catch,所以也叫做checked Exception。

不要忽略checked exceptions

我們知道checked exceptions是一定要被捕獲的異常,我們在捕獲異常之后通常有兩種處理方式。

第一種就是按照業(yè)務邏輯處理異常,第二種就是本身并不處理異常,但是將異常再次拋出,由上層代碼來處理。

如果捕獲了,但是不處理,那么就是忽略checked exceptions。

接下來我們來考慮一下java中線程的中斷異常。

java中有三個非常相似的方法interrupt,interrupted和isInterrupted。

isInterrupted()只會判斷是否被中斷,而不會清除中斷狀態(tài)。

interrupted()是一個類方法,調(diào)用isInterrupted(true)判斷的是當前線程是否被中斷。并且會清除中斷狀態(tài)。

前面兩個是判斷是否中斷的方法,而interrupt()就是真正觸發(fā)中斷的方法。

它的工作要點有下面4點:

如果當前線程實例在調(diào)用Object類的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法,或者在該實例中調(diào)用了Thread.sleep(long)或Thread.sleep(long,int)方法,并且正在阻塞狀態(tài)中時,則其中斷狀態(tài)將被清除,并將收到InterruptedException。

如果此線程在InterruptibleChannel上的I / O操作中處于被阻塞狀態(tài),則該channel將被關(guān)閉,該線程的中斷狀態(tài)將被設置為true,并且該線程將收到java.nio.channels.ClosedByInterruptException異常。

如果此線程在java.nio.channels.Selector中處于被被阻塞狀態(tài),則將設置該線程的中斷狀態(tài)為true,并且它將立即從select操作中返回。

如果上面的情況都不成立,則設置中斷狀態(tài)為true。

看下面的例子:

public void wrongInterrupted(){

try{

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

上面代碼中我們捕獲了一個InterruptedException,但是我們僅僅是打印出了異常信息,并沒有做任何操作。這樣程序的表現(xiàn)和沒有發(fā)送一異常一樣,很明顯是有問題的。

根據(jù)上面的介紹,我們知道,interrupted()方法會清除中斷狀態(tài),所以,如果我們自身處理不了異常的情況下,需要重新調(diào)用Thread.currentThread().interrupt()重新拋出中斷,由上層代碼負責處理,如下所示。

public void correctInterrupted(){

try{

Thread.sleep(1000);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}

不要在異常中暴露敏感信息

遇到異常的時候,通常我們需要進行一定程度的日志輸出,從而來定位異常。但是我們在做日志輸出的時候,一定要注意不要暴露敏感信息。

下表可以看到異常信息可能會暴露的敏感信息:

除了敏感信息之外,我們還要做好日志信息的安全保護。

在處理捕獲的異常時,需要恢復對象的初始狀態(tài)

如果我們在處理異常的時候,修改了對象中某些字段的狀態(tài),在捕獲異常的時候需要怎么處理呢?

private int age=30;

public void wrongRestore(){

try{

age=20;

throw new IllegalStateException(“custom exception!”);

}catch (IllegalStateException e){

System.out.println(“we do nothing”);

}

}

上面的例子中,我們將age重置為20,然后拋出了異常。雖然拋出了異常,但是我們并沒有重置age,最后導致age最終被修改了。

整個restore的邏輯沒有處理完畢,但是我們部分修改了對象的數(shù)據(jù),這是很危險的。

實際上,我們需要一個重置:

public void rightRestore(){

try{

age=20;

throw new IllegalStateException(“custom exception!”);

}catch (IllegalStateException e){

System.out.println(“we do nothing”);

age=30;

}

}

不要手動完成finally block

我們在使用try-finally和try-catch-finally語句時,一定不要在finally block中使用return, break, continue或者throw語句。

為什么呢?

根據(jù)Java Language Specification(JLS)的說明,finally block一定會被執(zhí)行,不管try語句中是否拋出異常。

在try-finally和try-catch-finally語句中,如果try語句中拋出了異常R,然后finally block被執(zhí)行,這時候有兩種情況:

如果finally block正常執(zhí)行,那么try語句被終止的原因是異常R。

如果在finally block中拋出了異常S,那么try語句被終止的原因?qū)兂蒘。

我們舉個例子:

public class FinallyUsage {

public boolean wrongFinally(){

try{

throw new IllegalStateException(“my exception!”);

}finally {

System.out.println(“Code comes to here!”);

return true;

}

}

public boolean rightFinally(){

try{

throw new IllegalStateException(“my exception!”);

}finally {

System.out.println(“Code comes to here!”);

}

}

public static void main(String[] args) {

FinallyUsage finallyUsage=new FinallyUsage();

finallyUsage.wrongFinally();

finallyUsage.rightFinally();

}

}

上面的例子中,我們定義了兩個方法,一個方法中我們在finally中直接return,另一方法中,我們讓finally正常執(zhí)行完畢。

最終,我們可以看到wrongFinally將異常隱藏了,而rightFinally保留了try的異常。

同樣的,如果我們在finally block中拋出了異常,我們一定要記得對其進行捕獲,否則將會隱藏try block中的異常信息。

不要捕獲NullPointerException和它的父類異常

通常來說NullPointerException表示程序代碼有邏輯錯誤,是需要程序員來進行代碼邏輯修改,從而進行修復的。

比如說加上一個null check。

不捕獲NullPointerException的原因有三個。

使用null check的開銷要遠遠小于異常捕獲的開銷。

如果在try block中有多個可能拋出NullPointerException的語句,我們很難定位到具體的錯誤語句。

最后,如果發(fā)生了NullPointerException,程序基本上不可能正常運行或者恢復,所以我們需要提前進行null check的判斷。

同樣的,程序也不要對NullPointerException的父類RuntimeException, Exception, or Throwable進行捕捉。

不要throw RuntimeException, Exception, or Throwable

我們拋出異常主要是為了能夠找到準確的處理異常的方法,如果直接拋出RuntimeException, Exception, 或者 Throwable就會導致程序無法準確處理特定的異常。

通常來說我們需要自定義RuntimeException, Exception, 或者 Throwable的子類,通過具體的子類來區(qū)分具體的異常類型。

不要拋出未聲明的checked Exception

一般來說checked Exception是需要顯示catch住,或者在調(diào)用方法上使用throws做申明的。

但是我們可以通過某些手段來繞過這種限制,從而在使用checked Exception的時候不需要遵守上述規(guī)則。

當然這樣做是需要避免的。我們看一個例子:

private static Throwable throwable;

private ThrowException() throws Throwable {

throw throwable;

}

public static synchronized void undeclaredThrow(Throwable throwable) {

ThrowException.throwable = throwable;

try {

ThrowException.class.newInstance();

} catch (InstantiationException e) {

} catch (IllegalAccessException e) {

} finally {

ThrowException.throwable = null;

}

}

上面的例子中,我們定義了一個ThrowException的private構(gòu)造函數(shù),這個構(gòu)造函數(shù)會throw一個throwable,這個throwable是從方法傳入的。

在undeclaredThrow方法中,我們調(diào)用了ThrowException.class.newInstance()實例化一個ThrowException實例,因為需要調(diào)用構(gòu)造函數(shù),所以會拋出傳入的throwable。

因為Exception是throwable的子類,如果我們在調(diào)用的時候傳入一個checked Exception,很明顯,我們的代碼并沒有對其進行捕獲:

public static void main(String[] args) {

ThrowException.undeclaredThrow(

new Exception(“Any checked exception”));

}

怎么解決這個問題呢?換個思路,我們可以使用Constructor.newInstance()來替代class.newInstance()。

try {

Constructor constructor =

ThrowException.class.getConstructor(new Class《?》[0]);

constructor.newInstance();

} catch (InstantiationException e) {

} catch (InvocationTargetException e) {

System.out.println(“catch exception!”);

} catch (NoSuchMethodException e) {

} catch (IllegalAccessException e) {

} finally {

ThrowException.throwable = null;

}

上面的例子,我們使用Constructor的newInstance方法來創(chuàng)建對象的實例。和class.newInstance不同的是,這個方法會拋出InvocationTargetException異常,并且把所有的異常都封裝進去。

所以,這次我們獲得了一個checked Exception。
編輯:hfy

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2997

    瀏覽量

    115785
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    508

    瀏覽量

    20770
  • 異常
    +關(guān)注

    關(guān)注

    0

    文章

    23

    瀏覽量

    9475
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    C++程序異常處理機制

    1、什么是異常處理? 有經(jīng)驗的朋友應該知道,在正常的C和C++編程過程中難免會碰到程序不按照原本設計運行的情況。 最常見的有除法分母為零,數(shù)組越界,內(nèi)存分配失效、打開相應文件失敗等等。 一個程序
    發(fā)表于 12-02 07:12

    快速定位MOS故障的常見方法與解決方案

    的關(guān)鍵。本文MDD將探討常見的MOS故障類型、故障排查方法以及相應的修復方案。一、常見的MOS故障類型MOS管無法導通或無法關(guān)斷這種故障通常
    的頭像 發(fā)表于 11-25 10:56 ?268次閱讀
    快速定位MOS故障的<b class='flag-5'>常見</b>方法與解決<b class='flag-5'>方案</b>

    晶振使用中常見問題與解決方法

    一、頻偏造成的使用異常異常現(xiàn)象:色彩圖像不正常;音頻雜音,無數(shù)據(jù)傳輸,距離短,遙控無反應。常見處理:換一個就OK根本原因:晶振負載電容同電路不匹配。解決辦法:調(diào)整電路匹配電容大小,或換
    的頭像 發(fā)表于 11-21 15:37 ?3699次閱讀
    晶振使用<b class='flag-5'>中常見</b>問題與解決方法

    線路保護光纖通道異常處理方法

    通道異常常見原因、處理步驟及預防措施 ,幫助運維人員快速定位問題,提升故障處理效率。 廣州郵科光纖線路保護系統(tǒng) 一、光纖通道異常
    的頭像 發(fā)表于 11-17 10:01 ?495次閱讀
    線路保護光纖通道<b class='flag-5'>異常</b><b class='flag-5'>處理</b>方法

    API接口調(diào)用中的網(wǎng)絡異常及解決方案

    一、連接類異常:“無法建立通信鏈路” 連接類異常的核心問題是 客戶端與API服務器之間無法成功建立TCP連接 ,導致調(diào)用請求“發(fā)不出去”,是網(wǎng)絡層最基礎的異常類型。 1.
    的頭像 發(fā)表于 11-17 09:22 ?372次閱讀

    如何處理電能質(zhì)量在線監(jiān)測裝置時鐘模塊自動同步異常的情況?

    針對性解決方案。以下是具體處理流程和操作方法: 一、通用前置步驟:明確異常類型與核心信息 處理前需先收集關(guān)鍵信息,避免盲目操作: 確認同步方
    的頭像 發(fā)表于 10-27 10:16 ?774次閱讀

    電能質(zhì)量在線監(jiān)測裝置時鐘模塊自動同步異常常見類型有哪些?

    : 一、PTP 同步(IEEE 1588)常見異常類型(適配 A 級裝置) PTP 同步依賴高精度鏈路與主從時鐘協(xié)同,異常多源于 “鏈路中斷、主時鐘失效或參數(shù)不匹配”,典型
    的頭像 發(fā)表于 10-22 14:15 ?248次閱讀

    【新啟航】玻璃晶圓 TTV 厚度測量數(shù)據(jù)異常的快速定位與解決方案

    ,研究玻璃晶圓 TTV 厚度測量數(shù)據(jù)異常的快速定位方法與解決方案,對保障生產(chǎn)效率和產(chǎn)品質(zhì)量具有重要意義。 二、數(shù)據(jù)異常常見類型 2.1
    的頭像 發(fā)表于 09-29 13:32 ?416次閱讀
    【新啟航】玻璃晶圓 TTV 厚度測量數(shù)據(jù)<b class='flag-5'>異常</b>的快速定位與解決<b class='flag-5'>方案</b>

    電能質(zhì)量在線監(jiān)測裝置能自動修復采樣異常數(shù)據(jù)嗎?

    展開分析: 一、數(shù)據(jù)異常類型與自動修復技術(shù)實現(xiàn) 1. 常見異常類型及自動處理機制 瞬時干擾數(shù)據(jù)由
    的頭像 發(fā)表于 09-26 09:22 ?274次閱讀
    電能質(zhì)量在線監(jiān)測裝置能自動修復采樣<b class='flag-5'>異常</b>數(shù)據(jù)嗎?

    【HarmonyOS 5】鴻蒙中常見的標題欄布局方案

    【HarmonyOS 5】鴻蒙中常見的標題欄布局方案 ##鴻蒙開發(fā)能力 ##HarmonyOS SDK應用服務##鴻蒙金融類應用 (金融理財# 一、問題背景: 鴻蒙中常見的標題欄:矩形區(qū)域,左邊
    的頭像 發(fā)表于 07-11 18:30 ?683次閱讀
    【HarmonyOS 5】鴻蒙<b class='flag-5'>中常見</b>的標題欄布局<b class='flag-5'>方案</b>

    射頻電路中常見的損耗類型

    射頻電路中的損耗是指在射頻信號傳輸、處理過程中,信號能量的減少。
    的頭像 發(fā)表于 03-17 11:29 ?1482次閱讀

    射頻電路中常見的元器件封裝類型有哪些

    射頻電路中常見的元器件封裝類型有以下幾種: 表面貼裝技術(shù)(SMT)封裝 方型扁平式封裝(QFP/PFP):引腳間距小、管腳細,適用于大規(guī)?;虺笮图呻娐?,可降低寄生參數(shù),適合高頻應用,外形尺寸
    的頭像 發(fā)表于 02-04 15:22 ?1261次閱讀

    數(shù)字電路中常見組件

    數(shù)字電路是由一系列電子組件組成的,它們處理的是二進制信號,即電壓水平的高低,通常對應于邏輯“0”和“1”。以下是數(shù)字電路中常見的一些組件,以及它們的基本功能和特點: 邏輯門(Logic Gates
    的頭像 發(fā)表于 01-24 09:40 ?1566次閱讀

    棱鏡——機器視覺系統(tǒng)中常見的重要配件

    棱鏡——機器視覺系統(tǒng)中常見的重要配件
    的頭像 發(fā)表于 01-15 17:36 ?866次閱讀
    棱鏡——機器視覺系統(tǒng)<b class='flag-5'>中常見</b>的重要配件

    串口通訊異常處理方法 串口設備連接方式

    串口通信異常處理方法 1. 異常檢測 在串口通信中,首先需要能夠檢測到異常情況。異常檢測可以通過以下幾種方式實現(xiàn): 硬件檢測 :利用串口硬件
    的頭像 發(fā)表于 12-27 09:53 ?5595次閱讀