JavaWeb 30 天入門:第七天 —— 異常處理機制

????????在前六天的學習中,我們掌握了 Java 的基礎語法、面向對象核心特性、抽象類與接口等知識。今天我們將學習 Java 中的異常處理機制,這是保證程序健壯性的關鍵技術。在 JavaWeb 開發中,無論是用戶輸入錯誤、數據庫連接失敗還是網絡異常,都需要通過異常處理機制來優雅地處理,避免程序崩潰并給用戶友好提示。

什么是異常?

異常(Exception)是程序運行過程中發生的意外情況,它會中斷程序的正常執行流程。例如:

  • 除以零(ArithmeticException
  • 訪問數組越界(ArrayIndexOutOfBoundsException
  • 讀取不存在的文件(FileNotFoundException
  • 網絡連接中斷

沒有異常處理的程序遇到異常時會直接崩潰,例如:

public class TestWithoutException {public static void main(String[] args) {int a = 10;int b = 0;System.out.println(a / b); // 發生算術異常System.out.println("程序繼續執行"); // 這行代碼不會執行}
}

運行結果:

Exception in thread "main" java.lang.ArithmeticException: / by zeroat TestWithoutException.main(TestWithoutException.java:5)

異常的分類

Java 中的異常體系以Throwable為根類,主要分為兩大類:

  1. Error(錯誤)

    • 由 JVM 產生的嚴重錯誤,程序無法處理(如內存溢出OutOfMemoryError
    • 通常不需要捕獲,需要從代碼層面解決
  2. Exception(異常)

    • 程序可以處理的異常,分為:
      • 編譯時異常(受檢異常):編譯期間必須處理的異常(如IOExceptionSQLException
      • 運行時異常(非受檢異常):運行時才會發生的異常(如NullPointerExceptionIndexOutOfBoundsException

異常體系結構簡圖:

Throwable
├─ Error(錯誤)
│  ├─ OutOfMemoryError
│  └─ StackOverflowError
│
└─ Exception(異常)├─ RuntimeException(運行時異常)│  ├─ NullPointerException│  ├─ ArithmeticException│  └─ IndexOutOfBoundsException│├─ IOException(編譯時異常)├─ SQLException(編譯時異常)└─ ClassNotFoundException(編譯時異常)

異常處理的核心語法

Java 提供了try-catch-finallythrows關鍵字來處理異常,確保程序在遇到異常時能夠繼續執行或優雅退出。

1. try-catch-finally 語句

try {// 可能發生異常的代碼塊
} catch (異常類型1 變量名1) {// 處理異常類型1的代碼
} catch (異常類型2 變量名2) {// 處理異常類型2的代碼
} finally {// 無論是否發生異常,都會執行的代碼(通常用于資源釋放)
}

執行流程

  • 如果try塊中沒有異常,執行try塊后直接執行finally
  • 如果try塊中有異常,中斷try塊執行,匹配對應的catch塊處理,最后執行finally

實例:

public class TryCatchDemo {public static void main(String[] args) {int[] nums = {1, 2, 3};try {// 可能發生異常的操作int result = 10 / 0; // 算術異常System.out.println(nums[3]); // 數組越界異常(不會執行)} catch (ArithmeticException e) {// 處理算術異常System.out.println("捕獲到算術異常:" + e.getMessage());e.printStackTrace(); // 打印異常堆棧信息(調試用)} catch (ArrayIndexOutOfBoundsException e) {// 處理數組越界異常System.out.println("捕獲到數組越界異常:" + e.getMessage());} finally {// 無論是否異常,都會執行System.out.println("finally塊執行:資源釋放操作");}// 異常處理后,程序可以繼續執行System.out.println("程序繼續運行...");}
}

運行結果:

捕獲到算術異常:/ by zero
java.lang.ArithmeticException: / by zeroat TryCatchDemo.main(TryCatchDemo.java:8)
finally塊執行:資源釋放操作
程序繼續運行...

2. throws 聲明異常

當方法內部無法處理異常時,可以使用throws關鍵字聲明該方法可能拋出的異常,由調用者處理:

// 聲明方法可能拋出的異常
修飾符 返回值類型 方法名(參數列表) throws 異常類型1, 異常類型2 {// 可能拋出異常的代碼
}

實例:

import java.io.FileInputStream;
import java.io.FileNotFoundException;public class ThrowsDemo {// 聲明可能拋出編譯時異常public static void readFile(String fileName) throws FileNotFoundException {// 讀取文件(可能拋出FileNotFoundException)new FileInputStream(fileName);}public static void main(String[] args) {try {// 調用聲明異常的方法,必須處理異常readFile("test.txt");} catch (FileNotFoundException e) {System.out.println("處理文件不存在異常:" + e.getMessage());}}
}

注意

  • 運行時異常可以不聲明,但編譯時異常必須聲明或捕獲
  • 子類重寫父類方法時,拋出的異常不能超過父類方法聲明的異常范圍

3. throw 主動拋出異常

使用throw關鍵字可以在代碼中主動拋出異常:

public class ThrowDemo {// 驗證年齡的方法public static void checkAge(int age) {if (age < 0 || age > 120) {// 主動拋出異常throw new IllegalArgumentException("年齡不合法:" + age);}System.out.println("年齡驗證通過:" + age);}public static void main(String[] args) {try {checkAge(150); // 調用方法} catch (IllegalArgumentException e) {System.out.println("捕獲到異常:" + e.getMessage());}}
}

運行結果:

捕獲到異常:年齡不合法:150

自定義異常

在實際開發中,系統提供的異常可能無法滿足業務需求,這時可以自定義異常類:

  1. 繼承Exception(編譯時異常)或RuntimeException(運行時異常)
  2. 提供構造方法(通常需要帶消息的構造方法)

實例:

// 自定義編譯時異常
public class InsufficientFundsException extends Exception {// 無參構造public InsufficientFundsException() {super();}// 帶消息的構造public InsufficientFundsException(String message) {super(message);}
}// 自定義運行時異常
public class InvalidAccountException extends RuntimeException {public InvalidAccountException(String message) {super(message);}
}// 使用自定義異常
public class BankService {private double balance; // 賬戶余額public BankService(double balance) {this.balance = balance;}// 取款方法(可能拋出自定義異常)public void withdraw(double amount) throws InsufficientFundsException {if (amount <= 0) {throw new InvalidAccountException("取款金額不能為負數");}if (amount > balance) {// 拋出編譯時異常,必須聲明throw new InsufficientFundsException("余額不足,當前余額:" + balance + ",取款:" + amount);}balance -= amount;System.out.println("取款成功,剩余余額:" + balance);}public static void main(String[] args) {BankService bank = new BankService(1000);try {bank.withdraw(1500);} catch (InsufficientFundsException e) {System.out.println("取款失敗:" + e.getMessage());} catch (InvalidAccountException e) {System.out.println("操作失敗:" + e.getMessage());}}
}

運行結果:

取款失敗:余額不足,當前余額:1000.0,取款:1500.0

異常處理的最佳實踐

  1. 避免捕獲所有異常:不要使用catch (Exception e)捕獲所有異常,應該針對性處理

    // 不推薦
    try {// ...
    } catch (Exception e) {// 無法區分具體異常類型
    }
    
  2. 不要忽略異常:捕獲異常后必須處理(至少記錄日志),避免空的catch

    // 不推薦
    try {// ...
    } catch (IOException e) {// 空塊會隱藏錯誤
    }
    
  3. 釋放資源:使用finally塊釋放資源(如文件流、數據庫連接)

    FileInputStream fis = null;
    try {fis = new FileInputStream("test.txt");// 讀取文件
    } catch (FileNotFoundException e) {e.printStackTrace();
    } finally {// 確保關閉流if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}
    }
    
  4. Java 7+:try-with-resources:自動釋放實現AutoCloseable接口的資源

    // 推薦:自動關閉資源,無需手動調用close()
    try (FileInputStream fis = new FileInputStream("test.txt")) {// 讀取文件
    } catch (IOException e) {e.printStackTrace();
    }
    
  5. 使用恰當的異常類型:根據業務場景選擇或創建合適的異常類型

異常處理在 JavaWeb 中的應用

在 JavaWeb 開發中,異常處理尤為重要,常見場景包括:

  1. Servlet 中的異常處理

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {String username = request.getParameter("username");if (username == null || username.isEmpty()) {throw new IllegalArgumentException("用戶名不能為空");}// 處理業務邏輯} catch (IllegalArgumentException e) {// 向客戶端返回錯誤信息response.getWriter().write("錯誤:" + e.getMessage());response.setStatus(400); // 設置HTTP錯誤狀態碼}
    }
    
  2. 全局異常處理器:在 Spring 等框架中,可以定義全局異常處理器統一處理異常,避免代碼冗余

總結與實踐

知識點回顧

  1. 異常概念:程序運行時的意外情況,會中斷正常執行流程
  2. 異常分類Error(無法處理)和Exception(可處理),Exception分為編譯時異常和運行時異常
  3. 處理方式
    • try-catch-finally:捕獲并處理異常,釋放資源
    • throws:聲明方法可能拋出的異常,由調用者處理
    • throw:主動拋出異常
  4. 自定義異常:繼承ExceptionRuntimeException,滿足業務需求
  5. 最佳實踐:針對性處理異常、不忽略異常、及時釋放資源

實踐任務

  1. 用戶注冊異常處理

    • 創建自定義異常UserAlreadyExistsException(用戶已存在)和InvalidUserInfoException(用戶信息無效)
    • 編寫UserService類,包含register(String username, String password)方法:
      • 如果用戶名已存在(可簡單判斷是否為 "admin"),拋出UserAlreadyExistsException
      • 如果密碼長度小于 6 位,拋出InvalidUserInfoException
      • 否則提示注冊成功
    • 編寫測試類,使用try-catch處理異常并輸出相應信息
  2. 文件讀取異常處理

    • 編寫FileUtil類,包含readFileContent(String filePath)方法,讀取文件內容
    • 處理可能的異常(文件不存在、IO 異常等)
    • 使用try-with-resources確保文件流正確關閉

思考:在 Web 開發中,為什么不建議直接將異常堆棧信息返回給客戶端?應該如何處理?

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

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

相關文章

編譯器默認生成的c++類六大成員函數

編譯器默認生成的c類六大成員函數 編譯器默認生成的六大成員函數 當你定義一個空類時&#xff0c;例如&#xff1a; class Empty {};如果代碼中沒有顯式定義任何成員函數&#xff0c;C編譯器會在需要時&#xff08;例如&#xff0c;代碼中實際調用了這些函數&#xff09;為你…

人工智能概念:常見的大模型微調方法

文章目錄一、微調技術的底層邏輯1.1 預訓練與微調的關系1.2 核心目標&#xff1a;適配任務與數據二、經典微調方法詳解2.1 全量微調&#xff08;Full Fine-Tuning&#xff09;2.2 凍結層微調&#xff08;Layer-Freezing Fine-Tuning&#xff09;2.3 參數高效微調&#xff08;Pa…

動態路由協議(一)

1. 動態路由 概述 靜態路由在大網絡里太麻煩&#xff08;設備多、配置量大&#xff0c;拓撲變了還要手動改&#xff09; 靜態路由是由工程師手動配置和維護的路由條目&#xff0c;命令行簡單明確&#xff0c;適用于小型或穩定的網絡。靜態路由有以下問題&#xff1a; 無法適…

LINUX812 shell腳本:if else,for 判斷素數,創建用戶

問題 [rootweb ~]# for((i2;i<n;i)) > if [ $n -ne $i ] && [ $((n%i)) -eq 0 ];then -bash: 未預期的符號 if 附近有語法錯誤 您在 /var/spool/mail/root 中有郵件 [rootweb ~]#[rootweb ~]# cat judgeprimeok.sh declare -i n read -p "please type the n…

游戲中角色持槍:玩家操控角色,角色轉向時槍也要轉向

角色持有槍&#xff0c;玩家&#xff08;你&#xff09;操控角色&#xff0c;那么&#xff0c;在角色轉向時&#xff0c;槍也要轉向。 先看看簡單情況&#xff1a;假定角色只面向左或右方向&#xff0c;pygame中用這句來實現&#xff1a;pos self.facing * self.gun_offset s…

深度學習入門Day8:生成模型革命——從GAN到擴散模型

一、開篇&#xff1a;創造力的算法革命從昨天的Transformer到今天的生成模型&#xff0c;我們正從"理解"世界邁向"創造"世界。生成對抗網絡(GAN)和擴散模型(Diffusion Model)代表了當前生成式AI的兩大主流范式&#xff0c;它們讓機器能夠生成逼真的圖像、音…

基于WRF-Chem的不同氣溶膠的輻射效應的研究

前言目前我對于氣溶膠輻射效應的理解就是設計敏感性實驗&#xff0c;基礎實驗打開氣溶膠參與輻射開關&#xff08;aer_ra_feedback&#xff09;&#xff0c;其他的實驗則關閉氣溶膠參與輻射過程開關&#xff0c;也有去掉某些氣溶膠的影響&#xff0c;如黑碳&#xff08;BC&…

專題:2025人形機器人與服務機器人技術及市場報告|附130+份報告PDF匯總下載

原文鏈接&#xff1a;https://tecdat.cn/?p43583 當特斯拉Optimus在工廠里精準分揀電池&#xff0c;當普渡機器人在酒店完成跨樓層配送&#xff0c;一個萬億級的智能革命正在拉開序幕。服務機器人與人形機器人不再是實驗室里的概念&#xff0c;而是正在重塑制造業、服務業的“…

JS 模塊化與打包工具

一、模塊化體系&#xff1a;ESM vs CJS 深入1.語法與靜態性(1)ESM:靜態語法&#xff0c;可被打包器做 Tree-shakingexport function play() {}export default ...import { play } from ./mod.js(2)CJS:運行時 require() , 分析能力弱&#xff0c;不利于 Tree-shaking2.Node 解析…

防御保護11

帶寬管理 --- 設備對自身的流量進行管理和控制&#xff0c;去提供帶寬保證、帶寬限制等等功能。 帶寬限制 帶寬保證 連接數限制 應用場景 實現帶寬管理 帶寬通道 --- 定義了被管理對象所能使用的帶寬資源 整體的保證帶寬和最大帶寬&#xff1b; SW1-SW2&#xff1a;VLAN 201 --…

[激光原理與應用-254]:理論 - 幾何光學 - 自動對焦的原理

自動對焦&#xff08;Auto Focus, AF&#xff09;是現代光學系統&#xff08;如相機、手機攝像頭、監控設備等&#xff09;的核心功能之一&#xff0c;其原理是通過檢測成像面的清晰度或測量物體距離&#xff0c;驅動透鏡組移動至最佳對焦位置。以下是自動對焦的詳細原理及技術…

【Python辦公】Mermaid代碼轉圖片工具 - Tkinter GUI版本

目錄 專欄導讀 項目簡介 功能特性 ?? 直觀的圖形界面 ?? 代碼編輯功能 ??? 圖片生成與預覽 ?? 文件操作 ? 性能優化 技術架構 核心技術棧 架構設計 安裝與使用 環境要求 依賴安裝 運行程序 使用步驟 代碼示例 基本流程圖 時序圖 甘特圖 核心代碼解析 1. 主類結構 2. …

【Activiti】要點初探

Activiti 7.0.0配置 流程配置節點流程XML流程部署部署后會操作表&#xff1a;&#xff08;每部署一次增加一條記錄&#xff09; ACT_RE_DEPLOYMENT 流程定義部署表 ACT_RE_PROCDEF 流程定義表 ACT_GE_BYTEARRAY 流程啟動查看任務&#xff08;張三要查看準備辦理任務&#xff0…

VBS 字符串處理

一. 字符串是由Unicode字符組成的一串字符。通常由數字&#xff0c;字母&#xff0c;符號組成。二. 常用函數1. 消除空格 Ltrim: 刪除字符串左側的空格。 Rtrim: 刪除字符串右側的空格。 trim: 刪除字符串左側和右側的空格。a" hello " b"sx"msgbo…

《算法導論》第 21 章-用于不相交集合的數據結構

引言不相交集合&#xff08;Disjoint Set&#xff09;&#xff0c;也稱為并查集&#xff08;Union-Find&#xff09;&#xff0c;是一種非常實用的數據結構&#xff0c;主要用于處理一些元素分組的問題。它支持高效的集合合并和元素查找操作&#xff0c;在很多算法中都有重要應…

基于51單片機RFID智能門禁系統紅外人流量計數統計

1 系統功能介紹 本設計基于STC89C52單片機&#xff0c;集成RFID讀卡器、紅外避障傳感器、繼電器、LCD1602液晶顯示和蜂鳴器&#xff0c;實現智能門禁與人流量統計功能。系統能夠識別合法的RFID卡開門&#xff0c;并實時統計通過人數&#xff0c;具有安全報警和直觀顯示功能。具…

c#,vb.net全局多線程鎖,可以在任意模塊或類中使用,但盡量用多個鎖提高效率

Public ReadOnly LockObj As New Object() 全局多線程鎖 VB.NET模塊中的LockObj 可以在任意模塊或類中使用吧 在 VB.NET 中&#xff0c;模塊&#xff08;Module&#xff09;中聲明的 Public ReadOnly LockObj 可以被其他模塊或類訪問和使用&#xff0c;但需要注意其可見性范圍…

企業安全運維服務計劃書

安全運維服務計劃書 一、概述 為保障企業信息系統安全、穩定、高效運行,防范各類網絡安全風險,提升整體安全防護能力,特制定本安全運維服務計劃書。本計劃旨在通過系統化、規范化的安全運維流程,全面識別、評估、處置并持續監控企業網絡環境中的安全風險,構建主動防御與…

小杰python高級(four day)——matplotlib庫

1.繪制子圖的方式pyplot中函數subplotFigure類中的函數add_subplotpyplot中函數subplotsfig, ax plt.subplots(nrows1, ncols1, *, sharexFalse, shareyFalse,squeezeTrue, subplot_kwNone, gridspec_kwNone, **fig_kw) 功能&#xff1a;繪制多個子圖&#xff0c;可以一次生成…

C# 編程out 參數需要在函數體內部初始化,然后引用的時候無需初始化

核心規則方法內部必須初始化&#xff1a;在方法體中&#xff0c;必須在方法返回前對 out 參數顯式賦值&#xff08;未賦值會導致編譯錯誤&#xff09;調用時無需初始化&#xff1a;調用方傳遞 out 參數前不需要初始化變量&#xff08;可直接使用未賦值的局部變量&#xff09;下…