Java提供了一個健壯的、面向?qū)ο蟮姆椒▉硖幚沓霈F(xiàn)異常,稱為Java異常處理。 我以前寫過一篇長文章來介紹Java異常處理,今天我將列出一些重要的Java異常面試的問題及答案,希望對你們的面試有所幫助。
1.什么是Java異常
答:異常是發(fā)生在程序執(zhí)行過程中阻礙程序正常執(zhí)行的錯誤事件。比如:用戶輸入錯誤數(shù)據(jù)、硬件故障、網(wǎng)絡(luò)阻塞等都會導(dǎo)致出現(xiàn)異常。 只要在Java語句執(zhí)行中產(chǎn)生了異常,一個異常對象就會被創(chuàng)建,JRE就會試圖尋找異常處理程序來處理異常。如果有合適的異常處理程序,異常對象就會被異常處理程序接管,否則,將引發(fā)運行環(huán)境異常,JRE終止程序執(zhí)行。 Java異常處理框架只能處理運行時錯誤,編譯錯誤不在其考慮范圍之內(nèi)。
2.Java異常處理中有哪些關(guān)鍵字?
答:
throw:有時我們需要顯式地創(chuàng)建并拋出異常對象來終止程序的正常執(zhí)行。throw關(guān)鍵字用來拋出并處理運行時異常。
throws:當(dāng)我們拋出任何“被檢查的異常(checked exception)”并不處理時,需要在方法簽名中使用關(guān)鍵字throws來告知調(diào)用程序此方法可能會拋出的異常。調(diào)用方法可能會處理這些異常,或者同樣用throws來將異常傳給上一級調(diào)用方法。throws關(guān)鍵字后可接多個潛在異常,甚至是在main()中也可以使用throws。
try-catch:我們在代碼中用try-catch塊處理異常。當(dāng)然,一個try塊之后可以有多個catch子句,try-catch塊也能嵌套。每個catch塊必須接受一個(且僅有一個)代表異常類型的參數(shù)。
finally:finally塊是可選的,并且只能配合try-catch一起使用。雖然異常終止了程序的執(zhí)行,但是還有一些打開的資源沒有被關(guān)閉,因此,我們能使用finally進行關(guān)閉。不管異常有沒有出現(xiàn),finally塊總會被執(zhí)行。
3.Java異常類有哪些的重要方法?
答:Exception和它的所有子類沒有提供任何特殊方法供使用,它們的所有方法都是來自其基類Throwable。
String getMessage():方法返回Throwable的String型信息,當(dāng)異常通過構(gòu)造器創(chuàng)建后可用。
String getLocalizedMessage():此方法通過被重寫來得到用本地語言表示的異常信息返回給調(diào)用程序。Throwable類通常只是用getMessage()方法來實現(xiàn)返回異常信息。
synchronized Throwable getCause():此方法返回異常產(chǎn)生的原因,如果不知道原因的話返回null。(原文有拼寫錯誤 應(yīng)該是if 不是id)
String toString():方法返回String格式的Throwable信息,此信息包括Throwable的名字和本地化信息。
void printStackTrace():該方法打印棧軌跡信息到標(biāo)準(zhǔn)錯誤流。該方法能接受PrintStream 和PrintWriter作為參數(shù)實現(xiàn)重載,這樣就能實現(xiàn)打印棧軌跡到文件或流中。
4.描述Java 7 ARM(Automatic Resource Management,自動資源管理)特征和多個catch塊的使用
答:如果一個try塊中有多個異常要被捕獲,catch塊中的代碼會變丑陋的同時還要用多余的代碼來記錄異常。有鑒于此,Java 7的一個新特征是:一個catch子句中可以捕獲多個異常。示例代碼如下:
catch(IOException | SQLException | Exception ex){
logger.error(ex);
throw new MyException(ex.getMessage());
}
大多數(shù)情況下,當(dāng)忘記關(guān)閉資源或因資源耗盡出現(xiàn)運行時異常時,我們只是用finally子句來關(guān)閉資源。這些異常很難調(diào)試,我們需要深入到資源使用的每一步來確定是否已關(guān)閉。因此,Java 7用try-with-resources進行了改進:在try子句中能創(chuàng)建一個資源對象,當(dāng)程序的執(zhí)行完try-catch之后,運行環(huán)境自動關(guān)閉資源。下面是這方面改進的示例代碼:
try (MyResource mr = new MyResource()) {
System.out.println("MyResource created in try-with-resources");
} catch (Exception e) {
e.printStackTrace();
}
6.被檢查的異常和不受檢查的異常有什么區(qū)別?
答:
A.被檢查的異常應(yīng)該用try-catch塊代碼處理,或者在main方法中用throws關(guān)鍵字讓JRE了解程序可能拋出哪些異常。不受檢查的異常在程序中不要求被處理或用throws語句告知。
B.Exception是所有被檢查異常的基類,然而,RuntimeException是所有不受檢查異常的基類。
C.被檢查的異常適用于那些不是因程序引起的錯誤情況,比如:讀取文件時文件不存在引發(fā)的FileNotFoundException。然而,不被檢查的異常通常都是由于糟糕的編程引起的,比如:在對象引用時沒有確保對象非空而引起的NullPointerException。
7.在Java中throw與throws關(guān)鍵字之間的區(qū)別?
答:throws用于在方法簽名中聲明此方法可能拋出的異常,而throw關(guān)鍵字則是中斷程序的執(zhí)行并移交異常對象到運行時進行處理。
8.在Java中怎么寫自定義的異常?
答:我們能繼承Exception類或其任何子類來實現(xiàn)自己的自定義異常類。這自定義異常類可以有自己變量和方法來傳遞錯誤代碼或其它異常相關(guān)信息來處理異常。
下面是一個簡單的自定義異常示例:
package com.journaldev.exceptions;
import java.io.IOException;
public class MyException extends IOException {
private static final long serialVersionUID = 4664456874499611218L;
private String errorCode="Unknown_Exception";
public MyException(String message, String errorCode){
super(message);
this.errorCode=errorCode;
}
public String getErrorCode(){
return this.errorCode;
}
}
9.在Java中什么是內(nèi)存不足錯誤?
答:在Java中,OutOfMemoryError是 java.lang.VirtualMachineError的一個子類,當(dāng)堆內(nèi)存耗盡時會被JVM拋出。我們能通過設(shè)置Java選項來提供更大的內(nèi)存供應(yīng)用使用來達到修復(fù)的目的。
$>java MyProgram -Xms1024m -Xmx1024m -XX:PermSize=64M -XX:MaxPermSize=256m
10.引發(fā)Exception in thread main的各種不同情形?
答:通常的一些主線程異常情形主要有以下幾種:
Exception in thread main java.lang.UnsupportedClassVersionError:當(dāng)編譯和運行Java類的JDK版本不同的時出現(xiàn)這種異常。
Exception in thread main java.lang.NoClassDefFoundError:這種異常出現(xiàn)的原因有兩種:第一種是提供類全名時附帶有.class;第二種是指定類未找到。
Exception in thread main java.lang.NoSuchMethodError: main:當(dāng)試圖運行一個沒main方法的類時會出現(xiàn)這種異常。
Exception in thread main java.lang.NoSuchMethodError: main:無論何時main方法任何異常,它打印異常到控制臺。其第一部分是陳述main方法拋出的異常,第二部分打印異常類名,后接異常類信息。
想了解更多這方面的內(nèi)容,請猛點這里。
11.Java中final,finally,finalize的區(qū)別?
答:final和finally在Java中是關(guān)鍵字,而finalize則是一個方法。
final關(guān)鍵字使得類變量不可變,避免類被其它類繼承或方法被重寫。finally跟try-catch塊一起使用,即使是出現(xiàn)了異常,其子句總會被執(zhí)行,通常,finally子句用來關(guān)閉相關(guān)資源。finally方法中的對象被銷毀之前會被垃圾回收。
綜上三者,只有finally用于異常處理。
12.在main方法拋出異常時發(fā)生了什么?
答:當(dāng)main方法拋出異常時,Java運行時間終止并在控制臺打印異常信息和棧軌跡。
13.catch子句能為空嗎?
答:可以有空的catch子句,但那是最糟糕的編程,因為那樣的話,異常即使被捕獲,我們也得不到任何的有用信息,對于調(diào)試來說會是個噩夢,因此,編程時永遠不要有空的catch子句。Catch子句中至少要包含一個日志語句輸出到控制臺或保存到日志文件中。