Java異常:認識異常、異常的作用、自定義異常

目錄

    • 1.什么是異常?
      • 1)運行時異常
      • 2)編譯時異常
    • 2.異常的作用
      • 1)Java 異常在定位 BUG 中的核心作用
      • 2)Java 異常作為方法內部特殊返回值的作用
      • 3)自定義異常

1.什么是異常?

在這里插入圖片描述
Error:代表的系統級別錯誤(屬于嚴重問題)
Exception:異常,代表的才是我們程序可能出現的問題,通常會用Exception以及它的子類來封裝程序出現的問題
運行時異常:RuntimeException及其子類,編譯階段不會出現錯誤提醒,運行時出現的異常(如:數組索引越界異常),通常因為編寫的代碼有問題導致
編譯時異常:編譯階段就會出現錯誤提醒的(如:日期解析異常),通常是Java官方對認為容易出問題的地方進行異常提醒,需要拋出異常或捕獲異常,對異常進行處理

1)運行時異常

int[] arr = {1,2,3};
System.out.println(arr[3]);
執行后報數組越界異常:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3at excepttion.Test.main(Test.java:6)System.out.println(10/0);
執行后報運算異常:
Exception in thread "main" java.lang.ArithmeticException: / by zeroat excepttion.Test.main(Test.java:5)String s = null;
System.out.println(s.length());
執行后報空指針異常:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "s" is nullat excepttion.Test.main(Test.java:6)

2)編譯時異常

在這里插入圖片描述
案例:處理異常可在方法名后使用throws關鍵字將異常拋給方法調用者處理或使用try…catch捕獲并拋出異常

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;public class Test {public static void main(String[] args) {String str = "2025-05-06";//存在編譯異常的方法調用時需使用try-catch塊處理異常或在main方法中使用throws關鍵字try {StringToDate(str); //調用方法轉換字符串為日期} catch (ParseException e) { //當字符串內容的格式不符合要求時(yyyy-MM-dd),會拋出ParseException異常e.printStackTrace(); //打印異常信息}}//定義轉換字符串為日期的方法并使用throws關鍵字拋出異常給調用者處理public static void StringToDate(String str) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//調用parse方法將字符串轉換成日期對象//此處出現編譯異常的原因:輸入的字符串格式和可能和SimpleDateFormat的格式不一致//例如需要輸入2019/09/09,但SimpleDateFormat的格式是yyyy-MM-dd//因此此處會拋出ParseException,解決方式:使用try...catch或者throws關鍵字Date date = sdf.parse(str);System.out.println(date);}
}

案例:存在多個編譯時異常可使用Exception接所有類型的異常

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;public class Test2 {public static void main(String[] args) {//使用try-catch塊處理異常try {StringToDate();} catch (Exception e) {e.printStackTrace();}}//使用Exception接收所有異常public static void StringToDate() throws Exception {String str = "2025-05-06";SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//出現ParseException異常Date date = sdf.parse(str);System.out.println(date);//創建讀取文件對象,拋出FileNotFoundException異常FileReader fr = new FileReader("d:/a.txt");}
}

2.異常的作用

Java 異常的作用分析:定位 BUG 與作為方法內部特殊返回值

1)Java 異常在定位 BUG 中的核心作用

Java 異常機制的核心價值之一是提供精準的錯誤定位能力,其通過異常堆棧跟蹤(Stack Trace)實現對程序運行時錯誤的可視化追蹤。當程序拋出未捕獲的異常時,JVM 會自動生成包含異常類型、發生位置及調用鏈路的堆棧信息,幫助開發者快速定位問題根源。
①異常堆棧跟蹤的信息構成
異常堆棧跟蹤是定位 BUG 的 “導航圖”,其結構包含三部分關鍵信息:
異常類型與消息:首行顯示異常的全限定類名(如java.lang.NullPointerException)及異常消息(如Cannot invoke “String.length()” because “s” is null),直接揭示錯誤類別及觸發原因;
堆棧幀序列:后續每行對應一個棧幀(StackTraceElement),包含異常傳播路徑中的調用信息,具體格式為at 類名.方法名(文件名:行號),其中行號是定位具體代碼位置的關鍵。

例如,執行以下代碼時:

public class Bug定位示例 {public static void main(String[] args) {String str = null;printLength(str); // 第4行:調用printLength方法}private static void printLength(String s) {System.out.println(s.length()); // 第8行:嘗試調用null對象的length()方法}
}

會拋出NullPointerException,其堆棧跟蹤信息如下:

java.lang.NullPointerException: Cannot invoke "String.length()" because "s" is nullat Bug定位示例.printLength(Bug定位示例.java:8)  // 異常發生點:第8行at Bug定位示例.main(Bug定位示例.java:4)        // 調用鏈路:main方法第4行觸發

②基于堆棧跟蹤的 BUG 定位流程

開發者可通過以下步驟定位 BUG:

識別異常類型:通過異常類名判斷錯誤類別(如NullPointerException表示空指針訪問,IndexOutOfBoundsException表示數組越界),縮小排查范圍;
解析異常消息:異常消息通常包含直接原因(如上述示例中s is null),可快速定位變量狀態異常;
追蹤堆棧幀鏈路:堆棧幀從下到上為調用鏈(最下方是異常發生點,上方是調用方),結合行號直接定位到具體代碼行(如示例中的第 8 行s.length()),進而檢查變量賦值、方法參數傳遞等上下文邏輯,最終找到根本原因(如 main 方法中str被賦值為null)。

③實戰價值:減少 “盲猜式” 調試

傳統調試依賴日志打印或斷點調試,需手動排查代碼執行路徑;而異常堆棧跟蹤直接標記錯誤發生的精確位置及傳播路徑,避免開發者在海量代碼中 “盲猜”。例如,在多層調用的復雜系統中(如 Controller→Service→DAO),異常堆棧可直接顯示異常是在 DAO 層 SQL 執行時拋出,還是在 Service 層參數校驗時觸發,大幅縮短定位時間。

2)Java 異常作為方法內部特殊返回值的作用

在方法設計中,除返回正常值外,常需傳遞 “特殊狀態”(如文件不存在、參數非法、業務規則沖突等)。傳統方案(如返回null、錯誤碼)存在信息缺失或易被忽略的問題,而 Java 異常可作為結構化的 “特殊返回值”,高效傳遞異常狀態并強制處理。

①傳統特殊狀態返回方案的局限性
錯誤碼方案:如返回-1表示 “參數錯誤”、-2表示 “資源不存在”,需開發者主動檢查返回值,若遺漏(如直接使用返回值參與運算),會導致錯誤傳播。例如:

// 錯誤碼方案示例(存在隱患)
public int divide(int a, int b) {if (b == 0) return -1; // 返回-1表示除數為0return a / b;
}
// 調用方可能忘記檢查錯誤碼,直接使用返回值:
int result = divide(5, 0);
System.out.println(result); // 輸出-1,錯誤被掩蓋

null返回方案:用null表示 “無結果”(如查詢不到數據),但調用方若未判空直接操作(如調用null對象的方法),會觸發NullPointerException,反而引入新錯誤。

②異常作為特殊返回值的優勢

強制關注特殊狀態:

受檢異常(Checked Exception):如IOException、ClassNotFoundException,編譯器強制要求調用方通過try-catch捕獲或throws聲明拋出,避免遺漏處理。例如,FileInputStream構造方法拋出FileNotFoundException(受檢異常),強制開發者處理 “文件不存在” 的場景:

// 受檢異常強制處理示例
public void readFile(String path) {try (FileInputStream fis = new FileInputStream(path)) { // 此處必須處理FileNotFoundException// 文件讀取邏輯} catch (FileNotFoundException e) {System.err.println("文件不存在:" + path); // 顯式處理特殊狀態} catch (IOException e) {System.err.println("文件讀取失敗:" + e.getMessage());}
}

非受檢異常(Unchecked Exception):如NullPointerException、IllegalArgumentException,雖不強制捕獲,但通過異常類型和消息提醒開發者關注(如參數校驗失敗),比null或錯誤碼更直觀。

3)自定義異常

異常可封裝比錯誤碼 /null更詳細的信息,包括:
異常類型:通過不同異常類區分特殊狀態類別(如IllegalArgumentException表示參數錯誤,TimeoutException表示超時);
異常消息:自定義文本描述具體原因(如"用戶ID=123不存在");
自定義字段:通過自定義異常類添加業務相關屬性(如錯誤碼、用戶 ID、操作類型等)。
例如,自定義業務異常傳遞多維度信息:

// 自定義異常作為特殊返回值(攜帶業務上下文)
class UserNotFoundException extends Exception {private final int userId; // 攜帶異常相關的用戶IDprivate final String errorCode; // 攜帶業務錯誤碼public UserNotFoundException(String message, int userId, String errorCode) {super(message);this.userId = userId;this.errorCode = errorCode;}// Getter方法獲取自定義字段public int getUserId() { return userId; }public String getErrorCode() { return errorCode; }
}// 方法中拋出自定義異常
public User getUserById(int id) throws UserNotFoundException {User user = userDao.query(id);if (user == null) {// 拋出異常時傳遞詳細信息:消息、用戶ID、錯誤碼throw new UserNotFoundException("用戶不存在", id, "USER_NOT_FOUND_001");}return user;
}// 調用方捕獲異常并獲取上下文
try {User user = getUserById(123); 
} catch (UserNotFoundException e) {log.error("查詢失敗:{},用戶ID:{},錯誤碼:{}", e.getMessage(), e.getUserId(), e.getErrorCode()); // 輸出:查詢失敗:用戶不存在,用戶ID:123,錯誤碼:USER_NOT_FOUND_001
}

(3)中斷錯誤流程,避免錯誤擴散

當方法遇到無法處理的特殊狀態時,拋出異常可立即中斷當前執行流程,阻止錯誤結果繼續傳播。例如,支付系統中若檢測到 “余額不足”,拋出InsufficientBalanceException可終止后續扣款邏輯,避免資金異常。

三、總結
Java 異常機制在程序開發中具有雙重核心價值:
定位 BUG:通過堆棧跟蹤提供異常發生的精確位置(類、方法、行號)及調用鏈路,是高效調試的 “導航系統”;

作為特殊返回值:相比錯誤碼 /null,異常通過強制處理機制(受檢異常)、豐富上下文信息(類型、消息、自定義字段)及流程中斷能力,更可靠地傳遞方法執行中的特殊狀態,提升代碼健壯性與可維護性。
合理使用異常機制,可顯著降低調試成本,減少因特殊狀態處理不當導致的系統故障。

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

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

相關文章

第十九天-輸入捕獲實驗

一、輸入捕獲概述1、輸入捕獲框圖2、輸入捕獲工作詳解①設置輸入捕獲濾波器可以設置濾波,濾除一些高電平脈寬不足的脈沖信號。②設置捕獲極性③輸入捕獲映射④輸入捕獲分頻器這里的捕獲是將計數器的值存入比較寄存器中,分頻次的作用是設置幾個上升沿/下降…

多線程問題,子線程同時操作全局變量,使用后需要清空嗎 ?

背景:目前有一個全局變量 ,某個方法中通過多線程,都操作這個變量,向這個全局變量中去添加元素,然后等所有子線程執行完了之后,對這個全局變量進行批量保存,然后這個全局變量還需要手動去清空嗎&…

Netty知識儲備:BIO、NIO、Reactor模型

學習Netty之前,首先先掌握這些基礎知識:阻塞(Block)與非阻塞(Non-Block),同步(Synchronous)與異步(Asynchronous),Java BIO與NIO對比。…

用生成器守住架構,用 AI 放大效率:一套可落地的 AI 編程方法論

背景與問題 現實困境: 直接讓 AI 產出整塊業務代碼,常常與現有架構風格、分層邊界、依賴策略不一致,后續改造成本高;AI 對現實業務語境、領域規則難以精準把握;在既定模板成熟的場景下,代碼生成器往往更快、更整齊。目…

碼頭岸電系統如何保障供電安全?安科瑞絕緣監測及故障定位方案解析

當岸電電網是TN-S系統時,船體未接專用接地線且船舶電網未與岸電零線接通,船舶電網發生單相接地故障時,人站在岸上觸及船體會有觸電危險,零線上可能出現高電壓,單相接地電流大。當船體接專用接地線且船舶電網接入岸電零…

ESP32_u8g2移植

前言 U8g2 是一個用于嵌入式設備的單色圖形庫。U8g2支持單色OLED和LCD,并支持如SSD1306 SSD1315等多種類型的OLED驅動,幾乎市面上常見都支持。 U8g2源碼 download:https://github.com/olikraus/u8g21:環境 ESP32 S3(ESP32-S3-Dev…

MCP實現:.Net實現MCP服務端 + Ollama ,MCP服務端工具調用

本文使用.Net編寫MCP服務端 Ollama ,實現簡單MCP調用,代碼僅實現基本演示功能。 文章目錄一、Ollama如何安裝使用二、創建.Net8項目,開發MCP服務端三、開發MCP客戶端,并對接Ollama一、Ollama如何安裝使用 請移步:htt…

Docker的安裝使用以及常見的網絡問題

一、什么是DockerDocker是一種容器化技術,用于快速打包、分發和運行程序。他的核心思想是"一次構建,到處運行",通過將應用及其依賴的環境打包到一個輕量級、可移植的容器中,實現跨平臺一致運行。二、Docker的安裝1.Cent…

C++入門學習

1.命名空間的介紹首先我們看到如下的代碼&#xff0c;在C語言中&#xff1a;#include <stdio.h> #include <stdlib.h> int rand 10; // C語言沒辦法解決類似這樣的命名沖突問題&#xff0c;所以C提出了namespace來解決 int main() {printf("%d\n", rand…

解決python錯誤:playwright._impl._errors.TimeoutError: Timeout 30000ms exceeded.

from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page() page.goto(url)page.wait_for_load_state(networkidle) 在Python環境中運行以上代碼后報錯: page.wait_for_load_…

爬蟲逆向之雷池waf

本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的。否則由此產生的一切后果均與作者無關&#xff01; 雷池waf概念 雷池 WAF&#xff08;SafeLine&#xff09;是長亭科技開源的一款 Web 應用防火墻&#xff0c;部署在網站前面&#xff0c;把所有進來的 HTTP/…

23種設計模式解析--行為型

行為型模式&#xff08;協作的藝術&#xff09; 觀察者模式 觀察者模式詳解 模式定義 觀察者模式&#xff08;Observer Pattern&#xff09;是一種行為設計模式&#xff0c;用于建立對象間一對多的依賴關系。當一個對象&#xff08;Subject&#xff09;狀態變化時&#xff0c;所…

Linux系統之lua 詳解

命令簡介 lua 是 Lua 語言的解釋器&#xff0c;用于加載和執行 Lua 程序&#xff08;包括文本源碼和預編譯的二進制文件&#xff09;。它支持兩種運行模式&#xff1a;批處理模式&#xff08;執行指定腳本文件&#xff09;和交互式模式&#xff08;逐行讀取并執行輸入的命令&am…

visual studio 無明顯錯誤,但是無法編譯成功解決—仙盟創夢IDE

往后面查看rror CS0246: 未能找到類型或命名空間名“SimpleClass”(是否缺少 using 指令或程序集引用?)修復阿雪技術觀在科技發展浪潮中&#xff0c;我們不妨積極投身技術共享。不滿足于做受益者&#xff0c;更要主動擔當貢獻者。無論是分享代碼、撰寫技術博客&#xff0c;還是…

《論文閱讀》傳統CoT方法和提出的CoT Prompting的區分

論文&#xff1a;Chain-of-Thought Prompting Elicits Reasoning in Large Language Models作者對傳統CoT方法和本文提出的CoT Prompting的區分。1. 傳統方法的局限性 (1) 基于微調的CoT&#xff08;Rationale-Augmented Training&#xff09; 實現方式&#xff1a;需人工標注大…

Minio 高性能分布式對象存儲

1、什么是對象存儲? 描述: 對象存儲&#xff08;Object Storage&#xff09;是一種存儲數據的計算機體系結構&#xff0c;它以對象的形式存儲和管理數據。與傳統的文件系統和塊存儲不同&#xff0c;對象存儲將數據作為對象存儲在分布式的存儲集群中&#xff0c;每個對象都有一…

[深度學習] 大模型學習4-RAG技術全景解析

在大語言模型基礎知識一文中&#xff0c;檢索增強生成&#xff08;Retrieval-Augmented Generation&#xff0c;簡稱 RAG&#xff09;技術作為構建大語言模型&#xff08;Large Language Model&#xff0c;簡稱 LLM&#xff09;應用的一種方式已被簡要提及&#xff0c;本文將詳…

4G/5G無線電單元系統

4G/5G無線電單元系統 ADI公司的核心技術和領域專業知識幫助客戶在全球范圍內規劃、設計、打造更出色的高性能通信系統。 我們的無線電單元(RU)設計平臺利用新一代技術來提供高性能解決方案&#xff0c;幫助客戶消除設計障礙、縮短產品開發周期&#xff0c;加快產品上市時間。 價…

HarvardX TinyML小筆記1(番外2:神經網絡)

1 介紹 圖片來自&#xff1a;https://zh.wikipedia.org/zh-cn/%E4%BA%BA%E5%B7%A5%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C 神經網絡一直感覺挺神奇的&#xff0c;江湖也說可解釋性很差&#xff0c;無論如何還是學學吧。借這次學習哈佛的TinyML&#xff0c;也就順帶弄了。 這里…

計算機網絡 第2章通信基礎(竟成)

第 2 章 物理層【考綱內容】1.通信基礎 (1) 信道、信號、帶寬、碼元、波特、速率、信源與信宿等基本概念 (2) 奈奎斯特定理與香農定理 (3) 編碼與調制 (4) 電路交換、報文交換與分組交換 (5) 數據報與虛電路2.傳輸介質 (1) 雙絞線、同軸電纜、光纖與無線傳輸介質&#xff1b;(2…