詳解Java中的異常體系機構(throw,throws,try catch,finally)


目錄

一.異常的概念

二.異常的體系結構

三.異常的處理

異常處理思路

LBYL:Look Before You Leap

EAFP: It's Easier to Ask Forgiveness than Permission

異常拋出throw

異常的捕獲

提醒聲明throws

?try-catch捕獲處理

finally的作用

四.自定義異常類


一.異常的概念

有一句話說的很好 ”程序員不是在寫BUG就是在改BUG” ,在日常開發中,程序員絞盡腦汁的去寫出完美的代碼,但是在程序運行過程中難免回遇見一些奇奇怪怪的問題。而這些問題與BUG總是很難去控制,用人類的思維去看明明是很完美的一個邏輯處理,但是交給編譯器就產生的結果總會與我們的預期大相徑庭,在Java中,我們將程序執行過程中發生的不正常的行為稱為異常,比如什么算數異常啊,數組越界異常啊,空指針異常啊這都屬于異常的范圍,我們統稱為異常

        System.out.println(10 / 0);// 執行結果Exception in thread "main" java.lang.ArithmeticExceptionint[] arr1 = {1, 2, 3};System.out.println(arr1[100]);// 執行結果Exception in thread "main" java.lang.ArrayIndexOutOfBoundsExceptionint[] arr2 = null;System.out.println(arr2.length);// 執行結果Exception in thread "main" java.lang.NullPointerException

并且我們可以看見在Java中對于不同的異常,都有對應的類來描述


二.異常的體系結構

實際上異常的種類是很多的,為了應對不同的異常或者錯誤,Java提供了一個非常龐大的異常體系機構供程序員來更好的維護代碼的安全性,如下圖所示

異常可能發生在編譯階段,可能發生在運行階段,因此我們可以按照異常發生的時間段將其進行分類:

  • 編譯時異常,也叫做受查異常
  • 運行時異常,也叫做非受查異常?

但是諸如將單詞拼寫錯誤導致的問題我們程序出現問題的情況不屬于異常


三.異常的處理

代碼中存在異常并不是什么奇怪的事情,但是在出現異常后,我們需要及時通知程序員去修改,對于異常的處理,我們分為倆種思路

異常處理思路

LBYL:Look Before You Leap

也就是說我們在操作之前就對異常做出充分的檢查,也就是事先防御型,比如我們在設計一款游戲的時候,我們就需要對其中可能發生的每一個錯誤做出處理機制和避免機制

        boolean ret = false;ret = loginGame();if (!ret) {//處理登陸游戲錯誤;return;}ret = startMatch();if (!ret) {//處理匹配錯誤;return;}ret = conGame();if (!ret) {//處理游戲確認錯誤;return;}ret = choiceChar();if (!ret) {//處理選擇英雄錯誤;return;}ret = loading();if (!ret) {//處理載入游戲錯誤;return;}

但這樣的處理會有一個缺陷:正常流程和錯誤處理流程代碼混在一起, 代碼整體顯的比較混亂

EAFP: It's Easier to Ask Forgiveness than Permission

這樣的思想主要解決的問題不是如何提前避免異常,而是在異常出現以后如何進行合理的應對

        try {loginGame();startMatch();conGame();choiceChar();loading();} catch (loginGame異常) {//處理登陸游戲錯誤;} catch (startMatch異常) {//處理匹配錯誤;} catch (conGame異常) {//處理游戲確認錯誤;} catch (choiceChar異常) {//處理選擇英雄錯誤;} catch (loading異常) {//處理載入游戲錯誤;}

在Java中對于異常處理的核心機制就是EAFP,Java中常用的有5個異常處理的關鍵字

  • throw
  • try
  • catch
  • final
  • throws

異常拋出throw

在Java中,可以借助throw關鍵字,拋出一個指定的異常對象,將錯誤信息告知給調用者。具體語法如下:

throw?new?XXXException?("異常產生的原因");

示例:?

    public static int getElement(int[] array, int index){if(null == array){throw new NullPointerException("傳遞的數組為null");}if(index < 0 || index >= array.length){throw new ArrayIndexOutOfBoundsException("傳遞的數組下標越界");}return array[index];}public static void main(String[] args) {int[] array = {1, 2, 3};getElement(array, 3);}

?注意:

  1. throw必須寫在方法體內部
  2. 拋出的對象必須是Exception 或者 Exception 的子類對象
  3. 如果拋出的是 RunTimeException 或者 RunTimeException的子類,則可以不用處理,直接交給JVM來處理
  4. 如果拋出的是編譯時異常,用戶必須處理,否則無法通過編譯
  5. 異常一旦拋出,其后的代碼就不會執行

異常的捕獲

異常的捕獲就是指我們對異常的處理,通常我們有倆種方式去處理:

  • 異常聲明throws
  • try-catch捕獲處理

提醒聲明throws

處在方法聲明時參數列表之后,當方法中拋出編譯時異常,用戶不想處理該異常,此時就可以借助throws將異常拋給方法的調用者來處理。也就是說當前方法不處理異常提醒方法的調用者處理異常

語法格式:

修飾符 返回值類型 方法名?(參數列表) throws 異常類型1,異常類型2...{

}

public class Config {File file;/*FileNotFoundException : 編譯時異常,表明文件不存在此處不處理,也沒有能力處理,應該將錯誤信息報告給調用者,讓調用者檢查文件名字是否給錯誤了*/public void OpenConfig(String filename) throws FileNotFoundException {if (filename.equals("config.ini")) {throw new FileNotFoundException("配置文件名字不對");}// 打開文件}
}

注意事項:

  • throws必須跟在方法參數列表之后
  • 拋出的問題必須是Exception 或者 Exception的子類對象
  • 方法內部如果拋出了多個異常,throws之后必須跟多個異常類型,之間用逗號隔開,如果拋出多個異常類型具有父子關系,直接聲明父類即可
  • 調用聲明拋出的異常方法時,調用者必須對異常做出處理,或者繼續使用throws拋出

示例:?

class Config {File file;// FileNotFoundException 繼承自 IOExceptionpublic void OpenConfig(String filename) throws IOException {if(filename.endsWith(".ini")){throw new IOException("文件不是.ini文件");}if(filename.equals("config.ini")){throw new FileNotFoundException("配置文件名字不對");}// 打開文件}public void readConfig(){}public void openConfig(String s) {}public static void main(String[] args) throws IOException {Config config = new Config();config.openConfig("config.ini");}
}

?try-catch捕獲處理

剛才我們提到的throws并沒有對異常做出處理,他只是將異常報給調用者,讓調用者去處理,而如果要對異常真正的處理就需要使用try-catch

try-catch的一般使用語法如下,其中catch:可以有一個也可以有多個,根據具體需求分配,finally可以有也可以沒有,但是如果有的話finally中的代碼就一定會執行,并且try中的代碼也可以不出現異常:

try{// 將可能出現異常的代碼放在這里}catch(要捕獲的異常類型 e){// 如果try中的代碼拋出異常了,此處catch捕獲時異常類型與try中拋出的異常類型一致時//或者是try中拋出異常的基類時,就會被捕獲到//對異常就可以正常處理,處理完成后,跳出try-catch結構,繼續執行后序代碼}catch(異常類型 e){// 對異常進行處理}finally{// 此處代碼一定會被執行到}
}

示例:

class Config {File file;public void openConfig(String filename) throws FileNotFoundException{if(!filename.equals("config.ini")){throw new FileNotFoundException("配置文件名字不對");}// 打開文件}public void readConfig(){}public static void main(String[] args) {Config config = new Config();try {config.openConfig("config.txt");System.out.println("文件打開成功");} catch (IOException e) {// 異常的處理方式//System.out.println(e.getMessage()); // 只打印異常信息//System.out.println(e); // 打印異常類型:異常信息e.printStackTrace(); // 打印信息最全面}// 一旦異常被捕獲處理了,此處的代碼會執行System.out.println("異常如果被處理了,這里的代碼也可以執行");}
}

注意:

  • ?try塊內拋出異常位置之后的代碼將不會被執行
  • ?如果拋出異常類型與catch時異常類型不匹配,即異常不會被成功捕獲,也就不會被處理,繼續往外拋,直到JVM收到后中斷程序----異常是按照類型來捕獲的
  • ?try中可能會拋出多個不同的異常對象,則必須用多個catch來捕獲----即多種異常,多次捕獲
  • 如果異常之間具有父子關系,一定是子類異常在前catch,父類異常在后catch,否則語法錯誤

finally的作用

在寫程序時,有些特定的代碼,不論程序是否發生異常,都需要執行,比如程序中打開的資源:網絡連接、數據庫連接、IO流等,在程序正常或者異常退出時,必須要對資源進進行回收。另外,因為異常會引發程序的跳轉,可能導致有些語句執行不到,finally就是用來解決這個問題的。

關于異常的處理方式,異常的種類有很多,我們要根據不同的業務場景來決定

  • 對于比較嚴重的問題(例如和算錢相關的場景), 應該讓程序直接崩潰, 防止造成更嚴重的后果
  • 對于不太嚴重的問題(大多數場景), 可以記錄錯誤日志, 并通過監控報警程序及時通知程序猿
  • 對于可能會恢復的問題(和網絡相關的場景), 可以嘗試進行重試
  • 在我們當前的代碼中采取的是經過簡化的第二種方式. 我們記錄的錯誤日志是出現異常的方法調用信息, 能很快速的讓我們找到出現異常的位置. 以后在實際工作中我們會采取更完備的方式來記錄異常信息

四.自定義異常類

Java中雖然已經內置了豐富的異常類, 但是并不能完全表示實際開發中所遇到的一些異常,此時就需要維護符合我們實際情況的異常結構,自定義異常通常會繼承自 ExceptionRunTimeException

  • 繼承自 Exception 的異常默認是受查異常
  • 繼承自 RunTimeException 的異常默認是非受查異常

具體方式:

  1. 自定義異常類,然后繼承自Exception 或者 RunTimeException
  2. 實現一個帶有String類型參數的構造方法,參數含義:出現異常的原因

例如我們實現一個用戶登陸功能:?

class UserNameException extends Exception {public UserNameException(String message) {super(message);}
}
class PasswordException extends Exception {public PasswordException(String message) {super(message);}
}
class LogIn {private String userName = "admin";private String password = "123456";public static void loginInfo(String userName, String password)throws UserNameException,PasswordException{if (!userName.equals(userName)) {throw new UserNameException("用戶名錯誤!");}if (!password.equals(password)) {throw new PasswordException("用戶名錯誤!");}System.out.println("登陸成功");}public static void main(String[] args) {try {loginInfo("admin", "123456");} catch (UserNameException e) {e.printStackTrace();} catch (PasswordException e) {e.printStackTrace();}}
}



?本次的分享就到此為止了,希望我的分享能給您帶來幫助,也歡迎大家三連支持,你們的點贊就是博主更新最大的動力!如有不同意見,歡迎評論區積極討論交流,讓我們一起學習進步!有相關問題也可以私信博主,評論區和私信都會認真查看的,我們下次再見

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166738.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166738.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166738.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微信小程序:This Mini Program cannot be opened as your Weixin version is out-of-date.

項目場景&#xff1a; 問題描述 升級基礎庫3.2.0&#xff0c;然后PC端整個小程序都打不開了&#xff0c;點擊小程序提示”This Mini Program cannot be opened as your Weixin version is out-of-date. Update Weixin to the latest version.“&#xff0c;并且點擊Update Wei…

一個悄然崛起的國產軟件!!AI 又進化了!!

大家好&#xff0c;我是 Jack。 AI 寫代碼想必很多人都體驗過了&#xff0c;使用 AI 編程工具是一個大趨勢&#xff0c;越早學會使用 AI 輔助你寫代碼&#xff0c;你的效率也會越高。 甚至有些公司已經要求員工具備 AI 編程能力。 對于學生黨&#xff0c;AI 編程可以幫助我們…

MyBatisPlus總結

MyBatis-Plus時Mybatis的Best Partner MyBatis-Plus (opens new window)&#xff08;簡稱 MP&#xff09;是一個 MyBatis (opens new window)的增強工具&#xff0c;在 MyBatis 的基礎上只做增強不做改變&#xff0c;為簡化開發、提高效率而生。 特性 無侵入損耗小強大的 CR…

Android開發從0開始(廣播)

應用廣播 發送標準廣播的三步驟 發送標準廣播&#xff1a; //發送標準廣播 Intent intent new Intent("com.dongnaoedu.chapter09.standard"); sendBroadcast(intent); 定義廣播接受者: public class StanderdReceiver extends BroadcastReceiver { public s…

在ASP.NET Core 中使用 .NET Aspire 消息傳遞組件

前言 云原生應用程序通常需要可擴展的消息傳遞解決方案&#xff0c;以提供消息隊列、主題和訂閱等功能。.NET Aspire 組件簡化了連接到各種消息傳遞提供程序&#xff08;例如 Azure 服務總線&#xff09;的過程。在本教程中&#xff0c;小編將為大家介紹如何創建一個 ASP.NET …

PLC通過RS232轉PROFINET與電子分析天平秤通訊案例

本案例是通過用興達易控的XD-PNR200型RS232轉Profinet網關連接電子分析天平秤與PLC通訊的配置案例&#xff0c;用到設備為西門子S7-1200PLC&#xff0c;RS232轉Profinet網關&#xff0c;電子分析天平秤。 打開博圖&#xff0c;添加PLC&#xff1b;本案例使用的是1200PLC。 添加…

『接口測試干貨』| Newman+Postman接口自動化測試完整過程

『接口測試干貨』| NewmanPostman接口自動化測試完整過程 1 Newman簡介2 如何安裝Newman&#xff1f;2.1 安裝NodeJs2.2 安裝Newman2.2 解決Newman不是內部命令 3 Newman使用3.1 Newman如何運行集合&#xff1f;3.2 如何查看幫助文檔&#xff1f;3.3 環境變量設置3.4 關于全局變…

微信小程序制作

如果你也想搭建一個小程序&#xff0c;但不知道如何入手&#xff0c;那么今天我就教你如何使用第三方制作平臺&#xff0c;在短短三十分鐘內搭建一個小程序。 一、登錄小程序制作平臺 首先&#xff0c;登錄到小程序制作平臺的官方網站或應用程序&#xff0c;進入后臺管理系統。…

【Oracle OCP考試】1z0-082(4)

1.Which two statements are true about the PMON background process? A. It rolls back transactions when a process fails&#xff08;當進程失敗時&#xff0c;它回滾事務&#xff09; B. It registers database services with all local and remote listeners known to…

文章解讀與仿真程序復現思路——電網技術 EI\CSCD\北大核心《考慮5G基站儲能可調度容量的有源配電網協同優化調度方法》

這篇文章的標題涉及到以下關鍵概念&#xff1a; 5G基站&#xff1a; 提到了5G基站&#xff0c;這表明文章的焦點可能是與第五代移動通信技術相關的內容。5G技術對于提高通信速度、降低延遲以及支持大規模連接等方面有顯著的改進&#xff0c;因此對于基站的電力需求和供應可能存…

2023年ESG投資研究報告

第一章 ESG投資概況 1.1 定義 ESG投資&#xff0c;亦稱負責任投資&#xff0c;是一種融合環境&#xff08;Environment&#xff09;、社會&#xff08;Social&#xff09;和治理&#xff08;Governance&#xff09;考量的投資方法&#xff0c;旨在通過綜合這些因素來優化投資…

美國汽車零部件巨頭 AutoZone 遭遇網絡攻擊

Security Affairs 網站披露&#xff0c;美國汽車配件零售商巨頭 AutoZone 稱其成為了 Clop MOVEit 文件傳輸網絡攻擊的受害者&#xff0c;導致大量數據泄露。 AutoZone 是美國最大的汽車零配件售后市場經銷商之一&#xff0c;在美國、墨西哥、波多黎各、巴西和美屬維爾京群島經…

算法-技巧-簡單-只出現一次的數字、多數元素

記錄一下算法題的學習10 只出現一次的數字 leetcode題目&#xff1a;給你一個 非空 整數數組 nums &#xff0c;除了某個元素只出現一次以外&#xff0c;其余每個元素均出現兩次。找出那個只出現了一次的元素。你必須設計并實現線性時間復雜度的算法來解決此問題&#xff0c;且…

「Whale 帷幄」連續入選科技榜單,AGI 沖擊波正在加速行業洗牌

以 AGI 為底座&#xff0c;品牌 MarTech 正在經歷一場前所未有的深度變革。 近日&#xff0c;彎弓研究院發布「中國 MarTech 500 強榜單」&#xff0c;以 2023 中國營銷技術&#xff08;MarTech&#xff09;生態為研究對象&#xff0c;洞察行業現象與未來趨勢。作為品牌數字化…

AMEYA360:蔡司新能源汽車解決方案驅動產業未來

電動化正在重塑中國汽車工業。自中國汽車工業開始發展以來&#xff0c;在電動化和智能化的浪潮推動下&#xff0c;汽車行業從未面臨著如此巨大的變革。得益于中國汽車產業尤其是新能源車過去十余年的激流勇進&#xff0c;消費者對新能源汽車的接受度也在發生轉變。新能源汽車市…

2016年全國碩士研究生入學統一考試管理類專業學位聯考英語(二)試題

Section IUse of English Directions: Read the following text.Choose the best word(s) for each numbered blank and mark A&#xff0c;B,Cor D on the ANSWER SHEET.(10 points)   Happy people work differently.They’re more productive&#xff0c;more creative&am…

前后端性能優化實踐(含Java代碼部分、數據庫部分、React前端部分)

最近的一個大屏報表統計的接口查詢速度很慢&#xff0c;耗時近一分鐘左右&#xff0c;數據量級只是700萬左右&#xff0c;但很慢&#xff0c;最后優化到4秒左右&#xff0c;客戶還能接受&#xff0c;但其實還可以在優化&#xff0c;先這樣吧&#xff0c;簡單記錄下。這次主要優…

App Inventor 2 文本轉數字

App Inventor 2 是弱語言類型&#xff0c;文本和數字之間不用刻意去轉換&#xff0c;之間賦值就可以了。文本賦值給數字變量如下&#xff1a; 運行結果&#xff1a;124 注意&#xff1a;數字變量初始化的時候要給一個數字的初始值&#xff0c;表明它是數字。 如果文本中含有非…

java與c++中的分支語句switch的不同

java中的switch后可用字符串,而C只能用字符和數字 switch(suffix){case "js":contentType"text/javascript";break;case "css":contentType"text/css";break;}c switch (x){case 0:case 1:case 2:rth 3;break;case 3:case 4:case 5:r…

系列三、事務

一、事務 1.1、概述 事務是數據庫操作的基本單元&#xff0c;它是指邏輯上的一組操作&#xff0c;要么都成功&#xff0c;要么都失敗。典型場景&#xff1a;轉賬&#xff0c;例如Jack給Rose轉賬1000元&#xff0c;轉賬成功&#xff1a;Jack賬戶的余額少1000元&#xff0c;Rose…