更新時(shí)間:2022-11-15 10:24:04 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽3215次
相信大家對(duì)Java的關(guān)鍵字已經(jīng)有所了解,在學(xué)習(xí)Java中了解如何在 Java 中拋出異常非常重要。這將允許您創(chuàng)建更高質(zhì)量的代碼,在編譯時(shí)而不是運(yùn)行時(shí)檢查錯(cuò)誤,并創(chuàng)建使調(diào)試和恢復(fù)更容易的自定義異常。
拋出異常就像使用“throw”語(yǔ)句一樣簡(jiǎn)單。然后指定Exception要拋出的對(duì)象。每個(gè) Exception 都包含一條消息,該消息是人類(lèi)可讀的錯(cuò)誤描述。它通常與用戶(hù)輸入、服務(wù)器、后端等問(wèn)題有關(guān)。下面是一個(gè)顯示如何拋出異常的示例:
throw new Exception("Exception message");
使用通用異常是有局限性的,因?yàn)樗拐{(diào)用代碼難以捕獲它。最好拋出自定義異常,稍后我們會(huì)回過(guò)頭來(lái)討論。
Throws是一個(gè)關(guān)鍵字,用于指示此方法可以拋出此類(lèi)異常。調(diào)用者必須使用try-catch塊處理異?;騻鞑ギ惓?。我們可以拋出已檢查或未檢查的異常。
throws關(guān)鍵字可以讓編譯器幫你寫(xiě)出處理這類(lèi)錯(cuò)誤的代碼,但它并不能阻止程序的異常終止。在throws關(guān)鍵字的幫助下,我們可以向方法的調(diào)用者提供有關(guān)該方法可能拋出的異常類(lèi)型的信息。
type method_name(parameters) throws exception_list
在上面的語(yǔ)法中,exception_list 是一個(gè)方法可能拋出的所有異常的逗號(hào)分隔列表。例如:
void testMethod() throws ArithmeticException, ArrayIndexOutOfBoundsException {
// rest of code
}
在下面的示例中,我們創(chuàng)建了一個(gè)測(cè)試方法來(lái)演示拋出異常。該toString()方法返回對(duì)象的文本表示,但在本例中變量為空。在空引用上調(diào)用方法或嘗試訪問(wèn)空引用的字段將觸發(fā)NullPointerException.
static void testMethod() throws Exception {
String test = null;
test.toString();
}
這必須用 try/catch 塊處理:
public class Example {
public static void main(String[] arg) {
try {
testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
}
要在您的應(yīng)用程序中更有效地使用異常,了解如何創(chuàng)建和拋出您自己的異常非常重要。但在我們開(kāi)始拋出異常之前,讓我們先深入了解一下:我們將描述異常是什么以及如何定義您自己的異常,從所有 Java 異常都源自的全局異常類(lèi)開(kāi)始:
package java.lang;
public class Exception extends Throwable {
static final long serialVersionUID = -3387516993124229948L;
public Exception() {
super();
}
public Exception(String message) {
super(message);
}
public Exception(String message, Throwable cause) {
super(message, cause);
}
public Exception(Throwable cause) {
super(cause);
}
protected Exception(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
該類(lèi)Exception是表示可恢復(fù)異常的所有類(lèi)的超類(lèi)。當(dāng)拋出異常時(shí),它們可能會(huì)被應(yīng)用程序代碼捕獲。異常類(lèi)擴(kuò)展Throwable。構(gòu)造函數(shù)包含兩個(gè)參數(shù):消息和原因。detailMessage 參數(shù)給出了這個(gè)異常的消息的詳細(xì)信息,throwable 參數(shù)給出了這個(gè)異常的原因。
Java 中有兩種類(lèi)型的異常:已檢查(編譯時(shí))異常和未檢查(運(yùn)行時(shí))異常。為清楚起見(jiàn),我們還將討論錯(cuò)誤與 Java 中的異常有何不同。
必須在編譯時(shí)捕獲和處理已檢查的異常。如果編譯器沒(méi)有看到tryorcatch塊或throws關(guān)鍵字來(lái)處理已檢查的異常,它會(huì)拋出一個(gè)編譯錯(cuò)誤。檢查異常通常是由代碼外部的錯(cuò)誤引起的,例如丟失文件、無(wú)效類(lèi)名和網(wǎng)絡(luò)錯(cuò)誤。
FileInputStream fis = null;
try {
fis = new FileInputStream("B:/myfile.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
rollbar.error(e, "Hello, Rollbar");
}
未經(jīng)檢查的異常不需要顯式處理;它們發(fā)生在執(zhí)行時(shí),也稱(chēng)為運(yùn)行時(shí)。這些異常通??梢酝ㄟ^(guò)良好的編碼實(shí)踐來(lái)避免。它們通常是由編程錯(cuò)誤引起的,例如邏輯錯(cuò)誤或 API 使用不當(dāng)。這些異常在編譯時(shí)被忽略。例如:
public class Main {
public static void main(String[] args) {
int a = 10, b = 0;
System.out.println(a/b);
}
}
上面的示例將ArithmeticException在程序運(yùn)行時(shí)引發(fā) an,因?yàn)閿?shù)字不能被 0 除。它會(huì)拋出未處理的異常,程序?qū)⒔Y(jié)束。
人們通常將“錯(cuò)誤”和“異常”通俗地稱(chēng)為同一事物。但是,在 Java 中,這些是不同的概念。錯(cuò)誤由 Java 虛擬機(jī)拋出,無(wú)法捕獲或處理。它們派生自 java.lang.Error,它們是由于應(yīng)用程序運(yùn)行環(huán)境中的某些錯(cuò)誤而發(fā)生的。例如,堆棧溢出和內(nèi)存不足異常是導(dǎo)致應(yīng)用程序退出的環(huán)境錯(cuò)誤。
Java 的內(nèi)置異常并不總能提供我們需要的信息。因此,我們有時(shí)需要用自己的異常來(lái)補(bǔ)充這些異常。在一些特定的操作過(guò)程中,如果你的應(yīng)用程序發(fā)生了異常,你需要恢復(fù)并讓用戶(hù)知道。自定義異常為您提供更多控制權(quán),以提供有關(guān)問(wèn)題的額外數(shù)據(jù)并處理代碼中的異常。
最佳實(shí)踐是使用新類(lèi)擴(kuò)展java.lang.Exception類(lèi),遵循 JDK(Java 開(kāi)發(fā)工具包)提供的一般命名約定。新類(lèi)需要一個(gè)將字符串作為錯(cuò)誤消息的構(gòu)造函數(shù)——它被稱(chēng)為父類(lèi)構(gòu)造函數(shù)。
public class HandledException extends Exception {
private String code;
public HandledException(String code, String message) {
super(message);
this.setCode(code);
}
public HandledException(String code, String message, Throwable cause) {
super(message, cause);
this.setCode(code);
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
例如,假設(shè)一個(gè)程序無(wú)法連接到數(shù)據(jù)庫(kù)。您可以使用自定義異常來(lái)收集數(shù)據(jù)庫(kù) URL、用戶(hù)名、密碼等信息。在該catch塊中,您可以將此信息寫(xiě)入日志并向用戶(hù)顯示一條基本消息,例如“無(wú)法連接到數(shù)據(jù)庫(kù)”。
public class MainClass {
private static String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
private static final Logger logger = Logger.getLogger(MainClass.class);
public static void main(String[] args) {
try {
makeDatabaseConnection();
} catch (HandledException e) {
rollbar.error(e, "Hello, Rollbar");
// Display custom message to the user
System.out.println("Code: "+e.getCode()+” Exception Message : ”+e.getMessage());
// Log the exception detail
logger.error("Exception: ", e);
}
}
static void makeDatabaseConnection() throws HandledException {
String dbURL = "jdbc:sqlserver://localhost\sqlexpress";
String userName = "sa";
String password = "secret";
Connection conn = null;
try {
conn = DriverManager.getConnection(dbURL, userName, password);
} catch (SQLException e) {
rollbar.error(e, "Hello, Rollbar");
throw new HandledException(DATABASE_EXCEPTION,"Failed to connect to database", e);
}
}
}
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)