Java異常類型及處理
一、異常定義
異常就是“意外、例外”的意思,也就是非正常情況。異常本質(zhì)上是程序上的錯(cuò)誤,包括程序邏輯錯(cuò)誤和系統(tǒng)錯(cuò)誤。異常的處理基本上就是用來(lái)兜底的,也是程序開(kāi)發(fā)中程序不愿意看到的。異常最基本的信息就是線程的堆棧信息。
二、異常的結(jié)構(gòu)和分類

Throwable主要分為Error和Exception。
錯(cuò)誤:Error類以及他的子類的實(shí)例,代表了JVM本身的錯(cuò)誤。錯(cuò)誤不能被程序員通過(guò)代碼處理,躺平解決就好,不要反抗。常見(jiàn)的錯(cuò)誤有下面這些

異常:Exception以及他的子類,代表程序運(yùn)行時(shí)發(fā)送的各種不期望發(fā)生的事件??梢员籎ava異常處理機(jī)制使用,是異常處理的核心,能在程序中解決的都不叫事。常見(jiàn)的異常有這么多。

三、異常的處理和捕獲
異常想要處理肯定要先捕獲到異常才可以,怎么捕獲異常吶,Java給我提供了幾個(gè)關(guān)鍵字,每個(gè)關(guān)鍵字怎么用吶?
1、try,catch 就是直接捕獲異常,catch 內(nèi)的異常類型是能捕獲的類型,一般如果有多個(gè)異常,從上到下的順序是異常范圍越來(lái)越大。注:ErrorCodeException的定義可以參考自定義異常。
public static void second(String[] args) {
try {
throw new ErrorCodeException("1123");
} catch (ErrorCodeException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
2、try catch finally 增加了finally關(guān)鍵字,就是在異常之后還能做一些事情,比如常見(jiàn)的關(guān)閉輸入流,輸出流,是程序最后的倔強(qiáng)。
public static String readFileContent(String fileName) {
File file = new File(fileName);
BufferedReader reader = null;
StringBuffer sbf = new StringBuffer();
try {
reader = new BufferedReader(new FileReader(file));
String tempStr;
while ((tempStr = reader.readLine()) != null) {
sbf.append(tempStr);
}
reader.close();
return sbf.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return sbf.toString();
}
3、throw 主要用來(lái)創(chuàng)建一個(gè)異常,因?yàn)槌绦蛑锌赡苄枰獟伋鲆粋€(gè)異常,比如我們游戲服務(wù)器游戲邏輯驗(yàn)證客戶端參數(shù)不通過(guò),會(huì)主動(dòng)拋出一個(gè)自定義的異常
4、throws 主要用在方法簽名上,當(dāng)我們讀寫(xiě)文件或者反射的時(shí)候,如果不用try catch 就會(huì)發(fā)現(xiàn)方法簽名后有一堆的異常需要處理。異常會(huì)繼續(xù)上拋給上層的調(diào)用方法,直至有方法處理或者給系統(tǒng)。
四、自定義異常
當(dāng)Java內(nèi)置的異常都不能明確的說(shuō)明異常情況的時(shí)候,需要?jiǎng)?chuàng)建自己的異常。
如果要自定義異常類,則繼承Exception類即可??梢栽陬愔性黾右恍┳约旱奶幚恚趧?chuàng)建異常的時(shí)候傳入,在處理異常的地方,可以根據(jù)具體的內(nèi)容進(jìn)行處理??梢钥聪孪旅娴膹棾隽鞒虘?yīng)用。
/**
* @author 香菜
*/
public class ErrorCodeException extends Exception {
//錯(cuò)誤碼
private String errorCode;
//構(gòu)造函數(shù)
public ErrorCodeException(String errorCode){
super(errorCode);
this.errorCode = errorCode;
}
public String getErrorCode() {
return errorCode;
}
}
五、異常的應(yīng)用
在游戲開(kāi)發(fā)中,每個(gè)協(xié)議的處理都會(huì)驗(yàn)證參數(shù)的是否合理,如果發(fā)現(xiàn)參數(shù)不合理,我們可以拋出一個(gè)自定義的參數(shù)異常,在同一的入口處進(jìn)行捕獲,解析出其中的錯(cuò)誤碼,直接發(fā)給客戶端。避免了一層一層的函數(shù)返回。
1.打印堆棧
有時(shí)候在調(diào)試代碼的過(guò)程中,因?yàn)楹瘮?shù)的調(diào)用處太多,游戲不好斷點(diǎn),我們可以在想要知道函數(shù)的調(diào)用路徑的情況下,可以隨意拋出一個(gè)異常,系統(tǒng)會(huì)打印出調(diào)用堆棧,幫忙定位問(wèn)題。是不是又獲得一個(gè)小技巧。
/**
* @author 香菜
*/
public class Aain {
public static void first(String[] args) throws Exception {
second(args);
}
public static void second(String[] args) throws Exception {
throw new Exception("1123");
}
public static void main(String[] args) throws Exception {
first(args);
}
}
2.彈出流程
/**
* @author 香菜
*/
public class Aain {
public static void first(String[] args) throws ErrorCodeException {
second(args);
}
public static void second(String[] args) throws ErrorCodeException {
third(args);
System.out.println("1111");
}
public static void third(String[] args) throws ErrorCodeException {
throw new ErrorCodeException("1123");
}
public static void main(String[] args){
try {
first(args);
} catch (ErrorCodeException e) {
e.printStackTrace();
}
}
}

從上面大堆棧打印可以看到,打印的語(yǔ)句沒(méi)有執(zhí)行,在游戲服務(wù)器的消息處理處捕獲一個(gè)ErrorCodeException,如果消息處理函數(shù)拋出這個(gè)異常,在入口處會(huì)捕獲并解析其中的錯(cuò)誤碼返回給客戶端,可以避免一層一層的返回函數(shù)。
六、注意點(diǎn)
1、Java程序可以是多線程的。每一個(gè)線程都是一個(gè)獨(dú)立的執(zhí)行流,獨(dú)立的函數(shù)調(diào)用棧。如果程序只有一個(gè)線程,那么沒(méi)有被任何代碼處理的異常 會(huì)導(dǎo)致程序終止。如果是多線程的,那么沒(méi)有被任何代碼處理的異常僅僅會(huì)導(dǎo)致異常所在的線程結(jié)束
2、finally 不具有再次處理異常的能力
3、不要只捕獲異常而不處理異常,就會(huì)發(fā)現(xiàn)不了問(wèn)題。
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多文章!
相關(guān)文章
淺析java實(shí)現(xiàn)數(shù)據(jù)加密問(wèn)題
本文通過(guò)實(shí)例代碼給大家介紹了java實(shí)現(xiàn)數(shù)據(jù)加密問(wèn)題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-11-11
Spring?Boot統(tǒng)一處理全局異常的實(shí)戰(zhàn)教程
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,所以下面這篇文章主要給大家介紹了關(guān)于Spring?Boot統(tǒng)一處理全局異常的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
大數(shù)據(jù) java hive udf函數(shù)的示例代碼(手機(jī)號(hào)碼脫敏)
這篇文章主要介紹了大數(shù)據(jù) java hive udf函數(shù)(手機(jī)號(hào)碼脫敏),的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
關(guān)于mybatis的一級(jí)緩存和二級(jí)緩存的那些事兒
MyBatis自帶的緩存有一級(jí)緩存和二級(jí)緩存,今天我們就來(lái)學(xué)習(xí)一下,文中有非常詳細(xì)的總結(jié),對(duì)正在學(xué)習(xí)的小伙伴們很有幫助,需要的朋友可以參考下2021-06-06
Spring整合Kaptcha谷歌驗(yàn)證碼工具的開(kāi)發(fā)步驟
這篇文章主要介紹了Spring整合Kaptcha谷歌驗(yàn)證碼工具的開(kāi)發(fā)步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
IDEA2020.2.3中創(chuàng)建JavaWeb工程的完整步驟記錄
這篇文章主要給大家介紹了關(guān)于IDEA2020.2.3中創(chuàng)建JavaWeb工程的完整步驟,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Java兩個(gè)乒乓球隊(duì)比賽名單問(wèn)題(判斷素?cái)?shù))
兩個(gè)乒乓球隊(duì)進(jìn)行比賽,各出三人。甲隊(duì)為a,b,c三人,乙隊(duì)為x,y,z三人。已抽簽決定比賽名單。有人向隊(duì)員打聽(tīng)比賽的名單。a說(shuō)他不和x比,c說(shuō)他不和x,z比,請(qǐng)編程序找出三隊(duì)賽手的名單2017-02-02
javaweb servlet中使用請(qǐng)求轉(zhuǎn)發(fā)亂碼的實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇javaweb servlet中使用請(qǐng)求轉(zhuǎn)發(fā)亂碼的實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
Java中的StringBuilder()常見(jiàn)方法詳解
StringBuilder是一個(gè)可變的字符序列,此類提供一個(gè)與 StringBuffer 兼容的 API,但不保證同步,這篇文章主要介紹了StringBuilder()常見(jiàn)方法,需要的朋友可以參考下2023-09-09

