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

Java中異常打印輸出的常見(jiàn)方法總結(jié)

 更新時(shí)間:2017年07月05日 17:08:12   作者:bladestone  
Java異常是在Java應(yīng)用中的警報(bào)器,下面這篇文章主要給大家介紹了關(guān)于Java中異常打印輸出的常見(jiàn)方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。

前言

Java異常是在Java應(yīng)用中的警報(bào)器,在出現(xiàn)異常的情況下,可以幫助我們程序猿們快速定位問(wèn)題的類(lèi)型以及位置。但是一般在我們的項(xiàng)目中,由于經(jīng)驗(yàn)閱歷等多方面的原因,依然有若干的童鞋在代碼中沒(méi)有正確的使用異常打印方法,導(dǎo)致在項(xiàng)目的后臺(tái)日志中,沒(méi)有收到日志或者日志信息不完整等情況的發(fā)生,這些都給項(xiàng)目埋下了若干隱患。本文將深入分析在異常日志打印過(guò)程中的若干情況,并給出若干的使用建議。

1. Java異常Exception的結(jié)構(gòu)分析

我們通常所說(shuō)的Exception主要是繼承于Throwable而來(lái),可以參見(jiàn)如下的結(jié)構(gòu)圖示:

主要的Throwable分為異常和錯(cuò)誤兩種,然后異常Exception和錯(cuò)誤Error做為基類(lèi),分別被具體個(gè)性化以及衍生出NullPointerException、EOFException等等異常信息類(lèi)。

基于Java中的源代碼來(lái)分析,Error和Exception僅僅是繼承了Throwable,做了構(gòu)造函數(shù)的拓展,沒(méi)有進(jìn)行額外方法的延展;Exception輸出的主要核心方法都是定義在Throwable中的,感興趣的童鞋可以嘗試閱讀JDK的源代碼。

下面將介紹一下關(guān)鍵的幾個(gè)異常類(lèi)方法:

1、getMessage(): String

輸出異常的描述信息

2、getLocalizedMessage()

輸出本地化的描述信息,一般此方法可被子類(lèi)所覆蓋,缺省實(shí)現(xiàn)與getMessage()輸出信息一致

3、printStackTrace()

將異常棧打印到輸出流中,此為一類(lèi)方法,默認(rèn)打印到console控制臺(tái),也可以顯式指定輸出流。

4、fillInStackTrace()

將當(dāng)前的異常棧保存到一個(gè)Throwable中,返回這個(gè)Throwable。大部分情況下,用在保留異常棧嵌套調(diào)用的情況,嘗試保留完整的異常棧,無(wú)需使用該方法。

2. Error vs Exception

Error在Java體系中定義為不可控制的問(wèn)題,往往用來(lái)描述系統(tǒng)錯(cuò)誤或者底層的問(wèn)題,比如虛擬機(jī)錯(cuò)誤,例如內(nèi)存空間不足,方法調(diào)用棧溢等。我們以上圖中列舉出的內(nèi)存溢出錯(cuò)誤(StackOverflowError)為例,它是在JVM層面發(fā)生的錯(cuò)誤,已經(jīng)游離于java應(yīng)用層之外;在應(yīng)用程序?qū)用媸菬o(wú)法進(jìn)行捕獲,且無(wú)法從錯(cuò)誤中恢復(fù)的。一般一旦發(fā)了類(lèi)似問(wèn)題,一般都是直接宕機(jī),應(yīng)用停止正常的工作,需要重新啟動(dòng)或者修復(fù)問(wèn)題之后,方可重新正常工作。

Exception一般發(fā)生在應(yīng)用層,即在由項(xiàng)目中的Java代碼層面引發(fā)的問(wèn)題,且可以嘗試進(jìn)行捕獲,此類(lèi)問(wèn)題不會(huì)影響到應(yīng)用程序的正常工作的,即不會(huì)導(dǎo)致宕機(jī)現(xiàn)象的發(fā)生。我們?cè)诠ぷ骰蛘叽a中常見(jiàn)的都是Exception衍生出來(lái)的各類(lèi)異常。

這里需要強(qiáng)調(diào)說(shuō)明一下,JVM是Java語(yǔ)言的運(yùn)行環(huán)境和平臺(tái),但是并不是Java語(yǔ)言體系的一個(gè)部分;在JVM平臺(tái)上,還可以運(yùn)行Groovy, JPython, JRuby, Closure,Scala等等遵守Java語(yǔ)言規(guī)范(JavaLanguage Specification)的編程語(yǔ)言,故我們可以將Error理解為脫離Java應(yīng)用之外的問(wèn)題。

3. Exception中的運(yùn)行時(shí)異常(RuntimeException)和受控異常(checked exception)

運(yùn)行時(shí)異常(RuntimeException)是指在運(yùn)行之時(shí)發(fā)生的異常,無(wú)需顯式地進(jìn)行捕獲;如果程序中發(fā)生類(lèi)似的異常,JVM會(huì)直接拋出此類(lèi)異常,并打出響應(yīng)的異常棧信息。此類(lèi)異常也通常被稱(chēng)為unchecked exception, 未受控異常。

受控異常(checked Exception)是我們最常見(jiàn)的異常種類(lèi),在代碼中使用的異常基本上都是此類(lèi)異常,此類(lèi)異常會(huì)在代碼編譯階段由Java編譯器進(jìn)行語(yǔ)法檢查,如果未顯式進(jìn)行異常捕獲,則會(huì)報(bào)出相應(yīng)的編譯異常信息。

4. 如何在代碼中正確打印異常信息

下面我們將通過(guò)一系列的例子來(lái)說(shuō)明上述幾個(gè)Exception中方法的使用技巧。

Case 1: getMessage()/getLocalizedMessage()

public void testCase1() {
System.out.println("We are going to do something interesting....");
try {
throw new NullPointerException("I am an exception in the code.");
} catch (Exception e) {
System.out.println("We got unexpected:" + e.getMessage());
System.out.println("We got unexpected:" + e.getLocalizedMessage());
}
}

輸出結(jié)果:

We are going to do testing interesting....
We got unexpected in getMessage==> I am an exception in the code.
We got unexpected in getLocalizedMessage==> I am an exception in the code.

基于結(jié)果來(lái)分析, 上述兩個(gè)方法只是將異常對(duì)象中的Message打印出來(lái),這些信息對(duì)于我們追蹤問(wèn)題和調(diào)試幫助有限。

Case 2:e.printStackTrace()

public void testCase2() {
System.out.println("We are going to do something interesting....");
try {
throw new Exception("I am an exception in the code.");
} catch (Exception e) {
e.printStackTrace();
}
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果圖

printStackTrace()可以打印出整個(gè)異常棧,但是異常棧信息將輸出到默認(rèn)的輸出流中,絕大多數(shù)情況下是系統(tǒng)的控制臺(tái),而在實(shí)際項(xiàng)目中,都是需要將異常棧輸出到日志文件的,如果不顯式指定,則會(huì)丟失異常信息,在日志文件中無(wú)從追查。

Case 3: 基于log4j/slf4j等輸出到日志文件

在實(shí)際項(xiàng)目中,一般會(huì)使用log4j/log4j2/JDK logging/slf4j/logback等日志系統(tǒng)來(lái)存放日志,那如何來(lái)講日志的異常棧存入日志文件呢,我們來(lái)看示例。

public void testCase3() {
System.out.println("We are going to do something interesting....");
try {
throw new NullPointerException("abcedfeg");
} catch (Exception e) {
logger.info("Unexpected error in ", e);
}
}

我們需要到日志文件中,找到相應(yīng)的異常信息,異常信息如下:

12:24:45.387 [main] INFO org.demo.TestException - Unexpected error in
java.lang.NullPointerException: abcedfeg
at org.demo.TestException.testCase3(TestException.java:39)
at org.demo.TestException.main(TestException.java:12)

我們可以發(fā)現(xiàn),整個(gè)異常棧信息由兩個(gè)部分組成:

>> 異常中的message, 類(lèi)似getMessage()輸出的信息,

>> 使用logger.info之類(lèi)的方法,將異常信息寫(xiě)入到日志流中.

以下為log4j的聲明,這里以slf4j為例來(lái)示例:

private static final Logger logger = LoggerFactory.getLogger(TestException.class); 

Case 4: fillInStackTrace()

public class FillInExceptionTest {
public static void main(String[] args) {
FillInExceptionTest fit = new FillInExceptionTest();
try {
fit.outerMehtod();
} catch (Exception e) {
System.out.println("\n==========I am the one evil separation line==============");
e.printStackTrace();
}
}
public void innerMethod() throws Exception {
throw new Exception("I got exception in an inner method.");
}
public void outerMehtod() throws Exception {
try {
innerMethod(); //invoke inner method.
} catch (Exception e) {
e.printStackTrace();
throw (Exception)e.fillInStackTrace();
}
}
}

運(yùn)行結(jié)果:

基于上述的運(yùn)行結(jié)果可知,fillInStackTrace()只提取了當(dāng)下的異常棧信息,而非完整的異常棧信息,這個(gè)就是此方法帶給我們的特殊之處。

如果我們需要在最外層將完整的異常棧打印出來(lái),該如何做呢? 將下述的語(yǔ)句:

throw (Exception)e.fillInStackTrace();

替換為:

throw e;

重新運(yùn)行程序,我們就可以在最外層得到完整的異常棧信息了。

5. 總結(jié)

在本文中,我們介紹了異常類(lèi)的繼承體系,不同類(lèi)型的異常區(qū)別與使用場(chǎng)景;并將基于代碼示例展示了如何使用Exception的若干方法,利用這些方法來(lái)保留盡可能多的日志信息,方便我們后續(xù)針對(duì)日志中的異常信息,追查和解決問(wèn)題。

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • SpringCloud之@FeignClient()注解的使用方式

    SpringCloud之@FeignClient()注解的使用方式

    這篇文章主要介紹了SpringCloud之@FeignClient()注解的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot實(shí)體多層嵌套判空字段的方式

    SpringBoot實(shí)體多層嵌套判空字段的方式

    這篇文章主要介紹了SpringBoot實(shí)體多層嵌套如何判空字段,最近在公司了接了個(gè)需求:需要開(kāi)發(fā)一個(gè)中間系統(tǒng),進(jìn)行三方聯(lián)調(diào),文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • idea項(xiàng)目結(jié)構(gòu)中不顯示out文件夾的解決

    idea項(xiàng)目結(jié)構(gòu)中不顯示out文件夾的解決

    本文通過(guò)圖片的方式詳細(xì)解釋操作步驟,使讀者能夠更直觀更方便地理解和執(zhí)行操作,同時(shí),文章末尾祝福讀者步步高升,一帆風(fēng)順,展現(xiàn)了作者的人情味和親和力,整體來(lái)說(shuō),這是一篇簡(jiǎn)單易懂、實(shí)用性強(qiáng)的操作指南
    2024-10-10
  • Java實(shí)踐練習(xí)輕松幾行實(shí)現(xiàn)追書(shū)神器

    Java實(shí)踐練習(xí)輕松幾行實(shí)現(xiàn)追書(shū)神器

    讀萬(wàn)卷書(shū)不如行萬(wàn)里路,只學(xué)書(shū)上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個(gè)追書(shū)神器,用技術(shù)改變生活,大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2021-10-10
  • Java實(shí)現(xiàn)解析JSON大文件JsonReader工具詳解

    Java實(shí)現(xiàn)解析JSON大文件JsonReader工具詳解

    這篇文章主要介紹了Java實(shí)現(xiàn)解析JSON大文件的工具JsonReader使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • Java成員變量的隱藏(實(shí)例講解)

    Java成員變量的隱藏(實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇Java成員變量的隱藏(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Java線程同步及實(shí)現(xiàn)方法詳解

    Java線程同步及實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了Java線程同步及實(shí)現(xiàn)方法詳解,當(dāng)我們有多個(gè)線程要同時(shí)訪問(wèn)一個(gè)變量或?qū)ο髸r(shí),如果這些線程中既有讀又有寫(xiě)操作時(shí),就會(huì)導(dǎo)致變量值或?qū)ο蟮臓顟B(tài)出現(xiàn)混亂,從而導(dǎo)致程序異常,需要的朋友可以參考下
    2023-11-11
  • 詳解Java如何進(jìn)行Base64的編碼(Encode)與解碼(Decode)

    詳解Java如何進(jìn)行Base64的編碼(Encode)與解碼(Decode)

    這篇文章主要介紹了詳解Java如何進(jìn)行Base64的編碼(Encode)與解碼(Decode),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • java實(shí)現(xiàn)文件下載的兩種方式

    java實(shí)現(xiàn)文件下載的兩種方式

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)文件下載的兩種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 配置javaw.exe雙擊運(yùn)行jar包方式

    配置javaw.exe雙擊運(yùn)行jar包方式

    這篇文章主要介紹了配置javaw.exe雙擊運(yùn)行jar包方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論