色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

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

454398 ? 來源:阿里云 ? 作者:阿里云原創 ? 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是一定要被捕獲的異常,我們在捕獲異常之后通常有兩種處理方式。

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

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

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

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

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

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

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

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

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

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

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

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

看下面的例子:

public void wrongInterrupted(){

try{

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

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

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

public void correctInterrupted(){

try{

Thread.sleep(1000);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}

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

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

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

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

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

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

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的邏輯沒有處理完畢,但是我們部分修改了對象的數據,這是很危險的。

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

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語句。

為什么呢?

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

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

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

如果在finally block中拋出了異常S,那么try語句被終止的原因將會變成S。

我們舉個例子:

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正常執行完畢。

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

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

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

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

比如說加上一個null check。

不捕獲NullPointerException的原因有三個。

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

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

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

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

不要throw RuntimeException, Exception, or Throwable

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

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

不要拋出未聲明的checked Exception

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

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

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

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構造函數,這個構造函數會throw一個throwable,這個throwable是從方法傳入的。

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

因為Exception是throwable的子類,如果我們在調用的時候傳入一個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方法來創建對象的實例。和class.newInstance不同的是,這個方法會拋出InvocationTargetException異常,并且把所有的異常都封裝進去。

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

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

    關注

    19

    文章

    2967

    瀏覽量

    104718
  • 線程
    +關注

    關注

    0

    文章

    504

    瀏覽量

    19677
  • 異常
    +關注

    關注

    0

    文章

    22

    瀏覽量

    9224
收藏 人收藏

    評論

    相關推薦

    soc開發流程常見問題及解決方案

    SOC(System on a Chip,系統級芯片)開發流程中常見問題及解決方案主要包括以下幾個方面: 一、環境問題 常見問題 : 開發環境配置復雜,新手難以快速上手。 依賴項缺失或
    的頭像 發表于 11-10 09:26 ?451次閱讀

    檢測系統中常見的信號類型有哪些

    在檢測系統中,常見的信號類型多種多樣,這些信號類型根據被測物理量的不同而有所區別。以下是一些常見的信號類型: 位移信號 :位移信號是檢測系統
    的頭像 發表于 10-15 13:57 ?518次閱讀

    放大電路中常見的噪聲有哪些

    在放大電路中,噪聲是一個不可忽視的問題,它會影響信號的純凈度和系統的性能。放大電路中的噪聲來源廣泛,包括電路元件本身、外部環境以及電路設計等多個方面。以下將詳細闡述放大電路中常見的噪聲類型,并探討其產生原因和特性。
    的頭像 發表于 09-03 14:03 ?686次閱讀

    嵌入式系統中常用的五種微處理類型

    本文介紹了嵌入式系統中常用的五種微處理類型:微處理器單元(MPU)、微控制器(MCU)、數字信號處理器(DSP)、現場可編程邏輯門陣列(F
    的頭像 發表于 07-25 09:29 ?1695次閱讀

    甲烷濃度檢測儀中常見的檢測技術及其應用

    甲烷濃度檢測儀中常見的檢測技術及其應用
    的頭像 發表于 07-08 10:47 ?608次閱讀
    甲烷濃度檢測儀<b class='flag-5'>中常見</b>的檢測技術及其應用

    一站式統一返回值封裝、異常處理異常錯誤碼解決方案—最強的Sping Boot接口優雅響應處理

    處理的邏輯集中到一個地方,避免代碼中出現大量的try-catch語句,降低了代碼的復雜度,提高了代碼的可讀性;異常體系的設計可以清晰地區分不同類型異常,使得開發者能夠更加精準地
    的頭像 發表于 06-20 15:42 ?529次閱讀

    伺服電機在工作中常見的問題有哪些?該怎么處理

    ??伺服電機作為現代工業自動化的核心組件,它的穩定運行對于整個生產流程至關重要。但就像任何機器一樣,伺服電機也會遇到一些頭疼的問題。今天,就讓我來給大家科普一下伺服電機在工作中常見的問題以及相應
    的頭像 發表于 03-16 08:42 ?732次閱讀

    變壓器運行中常見異常現象應如何處理呢?

    變壓器運行中常見異常現象應如何處理
    的頭像 發表于 03-08 09:19 ?615次閱讀
    變壓器運行<b class='flag-5'>中常見</b>的<b class='flag-5'>異常</b>現象應如何<b class='flag-5'>處理</b>呢?

    介紹C語言中錯誤處理異常處理的一些常用的方法和策略

    C語言是一種低級的、靜態的、結構化的編程語言,它沒有提供像C++或Java等高級語言中的異常處理機制,例如try-catch-finally等。
    的頭像 發表于 02-28 14:25 ?618次閱讀

    筆記本電腦中常見的電子元器件有哪些?

    筆記本電腦中常見的電子元器件有哪些? 筆記本電腦中常見的電子元器件包括以下幾類: 1. 中央處理器(CPU):CPU是筆記本電腦的核心部件,負責執行計算機的指令。常見的CPU品牌有In
    的頭像 發表于 02-02 10:19 ?2876次閱讀

    常見激光器類型

    23種最常見的激光器及其波長、工作模式和典型的增益介質。 氣體激光器,如氦氖(HeNe),由于其高光束質量和長相干長度,經常用于計量應用。其他類型的氣體激光器,如二氧化碳(CO2)激光器,經常用于材料加工,因為它們可以達到異常
    的頭像 發表于 01-24 06:44 ?1432次閱讀
    <b class='flag-5'>常見</b>激光器<b class='flag-5'>類型</b>

    GD32 串口接受異常幾個原因

    前面我們介紹過GD32 485發送時出現異常的最常見原因,有小伙伴反饋想要知道GD32 串口接受異常的可能原因,今天我們就來安排。
    的頭像 發表于 01-18 09:57 ?4229次閱讀
    GD32 串口接受<b class='flag-5'>異常</b>的<b class='flag-5'>幾個</b>原因

    如何解決C語言中的“訪問權限沖突”異常?C語言引發異常原因分析

    如何解決C語言中的“訪問權限沖突”異常?C語言引發異常原因分析? 在C語言中,訪問權限沖突異常通常是由于嘗試訪問未授權的變量、函數或其他數據結構而引起的。這種異常是編程
    的頭像 發表于 01-12 16:03 ?5653次閱讀

    Service層的異常處理

    一般初學者學習編碼和[錯誤處理]時,先知道[編程語言]有一種處理錯誤的形式或約定(如Java就拋異常),然后就開始用這些工具。但卻忽視這問題本質:「
    的頭像 發表于 01-08 11:29 ?571次閱讀

    伺服電機應用中常見干擾類型和產生途徑

    伺服電機應用中常見干擾類型和產生途徑
    的頭像 發表于 01-07 17:56 ?1399次閱讀
    主站蜘蛛池模板: 午夜成a人片在线观看| 久久久精品久久久久三级| 成人动漫bt种子| 91精品国产品国语在线不卡| 依人青青青在线观看| 一区二区三区国产亚洲网站| 亚洲色欲国产免费视频| 亚洲综合色在线视频久| 亚洲伊人网站| 在线免费观看视频a| 伊人色综合久久大香| 中文中幕无码亚洲在线| 4480yy午夜私人影院| 99热这里只有的精品| silk118中文字幕无删减| 成 人 动漫3d 在线看| 成人手机在线| 国产成人AV永久免费观看| 国产69精品久久久久APP下载| 国产1广场舞丰满老女偷| 国产情侣真实露脸在线| 国模沟沟一区二区三区| 久久九九日本韩国精品| 免费一区二区三区久久| 青苹果乐园在线观看电视剧| 涩涩爱涩涩电影网站| 亚洲AV福利天堂一区二区三| 亚洲视频 在线观看| 中文字幕一区二区三区在线不卡 | 午夜AV亚洲一码二中文字幕青青| 手机伊在人线香蕉2| 亚州性夜夜射在线观看| 伊人久久综合成人亚洲| 99久久精品国内| 国产精品久久久久久久人热| 国内精品久久| 免费人成网站在线观看10分钟| 日本特黄的免费大片视频| 无套内射在线观看THEPORN| 亚洲最大日夜无码中文字幕| 68日本xxxxxxxx79|