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

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

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

前言

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

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

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

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

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

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

1、getMessage(): String

輸出異常的描述信息

2、getLocalizedMessage()

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

3、printStackTrace()

將異常棧打印到輸出流中,此為一類方法,默認打印到console控制臺,也可以顯式指定輸出流。

4、fillInStackTrace()

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

2. Error vs Exception

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

Exception一般發(fā)生在應用層,即在由項目中的Java代碼層面引發(fā)的問題,且可以嘗試進行捕獲,此類問題不會影響到應用程序的正常工作的,即不會導致宕機現(xiàn)象的發(fā)生。我們在工作或者代碼中常見的都是Exception衍生出來的各類異常。

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

3. Exception中的運行時異常(RuntimeException)和受控異常(checked exception)

運行時異常(RuntimeException)是指在運行之時發(fā)生的異常,無需顯式地進行捕獲;如果程序中發(fā)生類似的異常,JVM會直接拋出此類異常,并打出響應的異常棧信息。此類異常也通常被稱為unchecked exception, 未受控異常。

受控異常(checked Exception)是我們最常見的異常種類,在代碼中使用的異常基本上都是此類異常,此類異常會在代碼編譯階段由Java編譯器進行語法檢查,如果未顯式進行異常捕獲,則會報出相應的編譯異常信息。

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

下面我們將通過一系列的例子來說明上述幾個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é)果來分析, 上述兩個方法只是將異常對象中的Message打印出來,這些信息對于我們追蹤問題和調(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();
}
}

運行結(jié)果:

運行結(jié)果圖

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

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

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

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);
}
}

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

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),整個異常棧信息由兩個部分組成:

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

>> 使用logger.info之類的方法,將異常信息寫入到日志流中.

以下為log4j的聲明,這里以slf4j為例來示例:

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();
}
}
}

運行結(jié)果:

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

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

throw (Exception)e.fillInStackTrace();

替換為:

throw e;

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

5. 總結(jié)

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

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

相關(guān)文章

最新評論

绵阳市| 榆树市| 锦屏县| 广元市| 时尚| 孟村| 绵阳市| 维西| 淮安市| 福安市| 闵行区| 贵定县| 交城县| 庆城县| 四川省| 上犹县| 黑山县| 浙江省| 会同县| 丽江市| 涿州市| 莱州市| 邳州市| 鄄城县| 敦化市| 广东省| 含山县| 泾阳县| 锦屏县| 陵水| 呼伦贝尔市| 南澳县| 枝江市| 自治县| 庄河市| 离岛区| 江城| 即墨市| 都江堰市| 镇远县| 高淳县|