最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java常見異常全面梳理(含分類+含義+典型場景)

 更新時(shí)間:2026年03月21日 09:45:30   作者:zhougl996  
異常是指程序在執(zhí)行過程中,出現(xiàn)的非正常情況,可能由程序員錯(cuò)誤、系統(tǒng)錯(cuò)誤或用戶輸入錯(cuò)誤引起,下面這篇文章主要介紹了Java常見異常全面梳理的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

Java 異常體系核心分為 運(yùn)行時(shí)異常(RuntimeException,非受檢)編譯時(shí)異常(Checked Exception 受檢),前者編譯期無需強(qiáng)制捕獲,由程序邏輯錯(cuò)誤導(dǎo)致;后者編譯期必須顯式捕獲/拋出,由外部環(huán)境(如IO、網(wǎng)絡(luò)、輸入)異常導(dǎo)致。此外,還有錯(cuò)誤(Error) 屬于JVM層面嚴(yán)重問題,通常無需程序處理。

區(qū)分「運(yùn)行時(shí)異常(預(yù)防為主)、受檢異常(強(qiáng)制處理)、JVM錯(cuò)誤(提前規(guī)避)」

一、運(yùn)行時(shí)異常(RuntimeException)—— 邏輯錯(cuò)誤主導(dǎo),預(yù)防優(yōu)先,捕獲兜底

繼承自java.lang.RuntimeException,編譯期無需強(qiáng)制處理,多由代碼邏輯不嚴(yán)謹(jǐn)導(dǎo)致,核心處理原則是通過嚴(yán)謹(jǐn)?shù)拇a邏輯從根源避免,僅對無法預(yù)防的場景做捕獲兜底。

1. NullPointerException(NPE)—— 開發(fā)最高頻異常

  • 核心含義:調(diào)用空對象的方法/屬性、對空對象執(zhí)行集合/數(shù)組操作,或自動(dòng)拆箱空包裝類
  • 典型場景Object obj = null; obj.toString();、Integer num = null; int n = num;、方法返回null未判空直接使用
  • 標(biāo)準(zhǔn)處理方式(按優(yōu)雅度排序,從基礎(chǔ)到高級)
    1. 基礎(chǔ)方案:顯式判空,對所有可能為null的對象執(zhí)行非空校驗(yàn);
    2. 優(yōu)雅方案:Java 8+ Optional類,包裝可能為null的對象,避免手動(dòng)判空;
    3. 校驗(yàn)方案:使用Objects.requireNonNull()做參數(shù)/對象非空校驗(yàn),快速定位空指針源頭;
    4. 開發(fā)規(guī)范:方法返回值盡量返回空集合/空對象(如Collections.emptyList()),而非null,減少調(diào)用方判空成本。
  • 核心代碼示例
// 1. 顯式判空
Object obj = getObj();
if (obj != null) {
    obj.toString();
}

// 2. Optional優(yōu)雅處理(推薦,無嵌套判空)
Optional.ofNullable(getObj()).ifPresent(o -> o.toString()); // 僅當(dāng)非空時(shí)執(zhí)行
String res = Optional.ofNullable(getStr()).orElse("默認(rèn)值"); // 空則返回默認(rèn)值

// 3. 非空校驗(yàn)(參數(shù)/方法內(nèi)對象,快速定位問題)
public void doWork(User user) {
    Objects.requireNonNull(user, "用戶對象不能為空");
    Objects.requireNonNull(user.getName(), "用戶名不能為空");
}
  • 避坑點(diǎn):切勿僅用if (obj != null)做多層嵌套判空(會(huì)導(dǎo)致代碼臃腫),優(yōu)先使用Optional。

2. ArrayIndexOutOfBoundsException —— 數(shù)組操作專屬

  • 核心含義:訪問數(shù)組的索引超出有效范圍(索引<0 或 索引>=數(shù)組長度)
  • 典型場景int[] arr = new int[3]; arr[3] = 10;、循環(huán)遍歷數(shù)組時(shí)條件寫為i <= arr.length
  • 標(biāo)準(zhǔn)處理方式
    1. 核心原則:遍歷數(shù)組始終以arr.length為邊界,循環(huán)條件用i < arr.length;
    2. 根源規(guī)避:使用增強(qiáng)for循環(huán)遍歷數(shù)組,無需手動(dòng)操作索引,從源頭避免越界;
    3. 前置校驗(yàn):手動(dòng)操作索引時(shí),先校驗(yàn)索引合法性(index >= 0 && index < arr.length)。
  • 核心代碼示例
int[] arr = {1,2,3};
// 1. 增強(qiáng)for循環(huán)(推薦,無索引操作)
for (int num : arr) {
    System.out.println(num);
}

// 2. 手動(dòng)索引操作(前置校驗(yàn))
int index = 3;
if (index >= 0 && index < arr.length) {
    System.out.println(arr[index]);
} else {
    System.err.println("索引越界,合法索引0-" + (arr.length-1));
}

3. IndexOutOfBoundsException(含子類StringIndexOutOfBoundsException)

  • 核心含義:訪問集合/字符串的索引超出有效范圍,是數(shù)組越界的「集合/字符串版」
  • 典型場景List<String> list = new ArrayList<>(); list.get(0);、"java".substring(5)
  • 標(biāo)準(zhǔn)處理方式
    1. 集合操作:遍歷用增強(qiáng)for循環(huán),手動(dòng)獲取元素前校驗(yàn)index < list.size()+集合非空(!list.isEmpty());
    2. 字符串操作:截取/獲取字符前校驗(yàn)index < str.length()+字符串非空(!str.isBlank());
    3. 工具輔助:使用org.apache.commons.lang3.StringUtils/CollectionUtils,避免原生方法的越界問題。
  • 核心代碼示例
List<String> list = Arrays.asList("a", "b");
String str = "java";
int index = 4;

// 集合安全獲取
if (!CollectionUtils.isEmpty(list) && index < list.size()) {
    System.out.println(list.get(index));
}

// 字符串安全截取(Apache工具類,越界會(huì)返回空/原字符串,無異常)
String sub = StringUtils.substring(str, 0, index); 

4. ClassCastException —— 類型轉(zhuǎn)換高頻異常

  • 核心含義:將對象強(qiáng)制轉(zhuǎn)換為其實(shí)際運(yùn)行時(shí)類型并非所屬的類/接口(無繼承/實(shí)現(xiàn)關(guān)系)
  • 典型場景Object obj = new Integer(10); String str = (String) obj;、泛型擦除后集合強(qiáng)轉(zhuǎn)元素
  • 標(biāo)準(zhǔn)處理方式
    1. 前置判斷:轉(zhuǎn)換前用instanceof校驗(yàn)對象實(shí)際運(yùn)行時(shí)類型,再執(zhí)行強(qiáng)轉(zhuǎn);
    2. 簡化方案:Java 14+ 模式匹配,一步完成「類型判斷+強(qiáng)制轉(zhuǎn)換」,簡化代碼;
    3. 根源規(guī)避:集合操作強(qiáng)制指定泛型(如List<String> list = new ArrayList<>()),編譯期攔截非目標(biāo)類型元素。
  • 核心代碼示例
Object obj = new Integer(10);
// 1. 傳統(tǒng)方式:instanceof判斷+強(qiáng)轉(zhuǎn)
if (obj instanceof String) {
    String str = (String) obj;
}

// 2. Java14+ 模式匹配(推薦,少一層代碼)
if (obj instanceof String str) {
    System.out.println(str.length());
}

// 3. 泛型規(guī)避(從根源避免)
List<String> list = new ArrayList<>();
list.add("java");
// list.add(10); // 編譯期直接報(bào)錯(cuò),無法添加非String類型

5. InputMismatchException —— Scanner輸入專屬

  • 核心含義java.util.Scanner讀取數(shù)據(jù)時(shí),輸入數(shù)據(jù)類型與預(yù)期讀取類型不兼容
  • 典型場景:用scanner.nextInt()讀整數(shù),用戶輸入字符串(“abc”)、小數(shù)(3.14)
  • 標(biāo)準(zhǔn)處理方式(核心:清空輸入緩沖區(qū),避免死循環(huán)
    1. 推薦方案:先判斷再讀取,使用Scanner的hasNextXxx()系列方法匹配讀取方法(hasNextInt()對應(yīng)nextInt());
    2. 兜底方案:捕獲異常后,必須調(diào)用scanner.next()清空緩沖區(qū)的無效數(shù)據(jù);
    3. 萬能方案:先讀取原始字符串,再通過包裝類手動(dòng)轉(zhuǎn)換,配合try-catch處理。
  • 核心代碼示例(推薦方案,無異常)
Scanner scanner = new Scanner(System.in);
int num = 0;
while (true) {
    System.out.print("請輸入整數(shù):");
    if (scanner.hasNextInt()) {
        num = scanner.nextInt();
        break; // 輸入合法,退出循環(huán)
    } else {
        System.err.println("輸入錯(cuò)誤,僅支持整數(shù)!");
        scanner.next(); // 關(guān)鍵:清空緩沖區(qū)的無效數(shù)據(jù),避免死循環(huán)
    }
}

6. ArithmeticException —— 數(shù)值計(jì)算錯(cuò)誤

  • 核心含義:算術(shù)運(yùn)算中出現(xiàn)非法操作,整數(shù)除零/取模模數(shù)為0是最典型場景
  • 典型場景int a = 10 / 0;、10 % 0(注:浮點(diǎn)數(shù)除零結(jié)果為Infinity,不會(huì)觸發(fā)此異常)
  • 標(biāo)準(zhǔn)處理方式
    1. 前置校驗(yàn):對除法/取模的除數(shù)/模數(shù)做非零校驗(yàn),從根源避免;
    2. 異常兜底:捕獲異常后,根據(jù)業(yè)務(wù)返回默認(rèn)值或拋出自定義提示,避免程序崩潰。
  • 核心代碼示例
int a = 10, b = 0;
int res = 0;
// 前置校驗(yàn)(推薦)
if (b != 0) {
    res = a / b;
} else {
    System.err.println("除數(shù)不能為零");
    res = 0; // 業(yè)務(wù)默認(rèn)值
}

// 異常兜底(無法提前校驗(yàn)的場景)
try {
    res = a / b;
} catch (ArithmeticException e) {
    System.err.println("計(jì)算失?。撼龜?shù)不能為零");
    res = 0;
}

7. IllegalArgumentException —— 參數(shù)非法通用異常

  • 核心含義:方法接收到不符合業(yè)務(wù)要求的非法參數(shù),是自定義方法參數(shù)校驗(yàn)的標(biāo)準(zhǔn)異常
  • 典型場景:方法要求參數(shù)>0卻傳入-1、要求非空字符串卻傳入空串、Collections.sort(null)
  • 標(biāo)準(zhǔn)處理方式
    1. 主動(dòng)拋出:方法入口處做參數(shù)校驗(yàn),參數(shù)不合法時(shí)主動(dòng)拋出該異常,并攜帶明確的錯(cuò)誤提示;
    2. 工具輔助:使用Objects/Apache Commons工具類簡化參數(shù)校驗(yàn),避免重復(fù)代碼;
    3. 框架適配:Spring項(xiàng)目可使用@Valid/@NotBlank等注解做參數(shù)自動(dòng)校驗(yàn),無需手動(dòng)判斷。
  • 核心代碼示例
// 手動(dòng)參數(shù)校驗(yàn)+主動(dòng)拋出異常(推薦,語義清晰)
public void setAge(int age) {
    if (age < 0 || age > 150) {
        throw new IllegalArgumentException("年齡必須在0-150之間,當(dāng)前值:" + age);
    }
    this.age = age;
}

// Spring項(xiàng)目注解校驗(yàn)(簡化代碼)
public void addUser(@Valid User user) {
    // User類中:@NotBlank(message = "用戶名不能為空") private String name;
}

8. NumberFormatException —— 數(shù)值格式轉(zhuǎn)換錯(cuò)誤

  • 核心含義:將非數(shù)值格式的字符串轉(zhuǎn)換為int/double/long等數(shù)值類型時(shí)觸發(fā)
  • 典型場景Integer.parseInt("123a");Double.parseDouble("3.14.5");、前端傳參非數(shù)值字符串后端直接轉(zhuǎn)換
  • 標(biāo)準(zhǔn)處理方式
    1. 異常捕獲:轉(zhuǎn)換時(shí)通過try-catch捕獲異常,返回業(yè)務(wù)默認(rèn)值或提示格式錯(cuò)誤;
    2. 工具輔助:使用org.apache.commons.lang3.math.NumberUtils,轉(zhuǎn)換失敗返回默認(rèn)值,無需手動(dòng)捕獲;
    3. 前置校驗(yàn):轉(zhuǎn)換前通過正則表達(dá)式校驗(yàn)字符串是否為合法數(shù)值(如^\\d+$匹配整數(shù))。
  • 核心代碼示例
String str = "123a";
// 1. try-catch兜底
int num1 = 0;
try {
    num1 = Integer.parseInt(str);
} catch (NumberFormatException e) {
    System.err.println("數(shù)值格式錯(cuò)誤,默認(rèn)值為0");
}

// 2. NumberUtils工具類(推薦,簡化代碼)
int num2 = NumberUtils.toInt(str, 0); // 轉(zhuǎn)換失敗返回默認(rèn)值0
double num3 = NumberUtils.toDouble(str, 0.0);

9. ConcurrentModificationException —— 集合并發(fā)修改錯(cuò)誤

  • 核心含義:單/多線程中,遍歷集合的同時(shí)執(zhí)行結(jié)構(gòu)性修改(增/刪/修改集合容量)
  • 典型場景:增強(qiáng)for循環(huán)遍歷List時(shí)調(diào)用list.remove()、多線程同時(shí)操作非線程安全集合(ArrayList/HashMap)
  • 標(biāo)準(zhǔn)處理方式(分單/多線程場景)
    1. 單線程:使用迭代器(Iterator) 遍歷并修改,調(diào)用it.remove(),這是集合遍歷修改的標(biāo)準(zhǔn)方式;
    2. 多線程:替換為線程安全集合CopyOnWriteArrayList替代ArrayList、ConcurrentHashMap替代HashMap);
    3. 兜底方案:遍歷前將集合轉(zhuǎn)為數(shù)組,或遍歷過程中收集需要修改的元素,遍歷完成后統(tǒng)一處理。
  • 核心代碼示例
List<String> list = new ArrayList<>();
list.add("a"); list.add("b"); list.add("c");

// 1. 單線程安全修改(迭代器)
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if ("a".equals(it.next())) {
        it.remove(); // 無異常,標(biāo)準(zhǔn)方式
    }
}

// 2. 多線程安全集合(直接替換,無需修改業(yè)務(wù)代碼)
List<String> safeList = new CopyOnWriteArrayList<>();
Map<String, String> safeMap = new ConcurrentHashMap<>();

10. UnsupportedOperationException —— 不支持的操作

  • 核心含義:調(diào)用了對象未實(shí)現(xiàn)/不支持的方法,多為只讀/固定長度對象的修改操作
  • 典型場景Arrays.asList(arr).add(1);(該List為固定長度)、對Collections.unmodifiableList()執(zhí)行增刪
  • 標(biāo)準(zhǔn)處理方式
    1. 根源規(guī)避:若需修改數(shù)組轉(zhuǎn)換的List,重新創(chuàng)建可修改集合new ArrayList<>(Arrays.asList(arr)));
    2. 開發(fā)規(guī)范:使用集合前確認(rèn)其類型,避免對只讀集合執(zhí)行修改操作;
    3. 前置判斷:通過集合的class判斷是否為可修改類型(兜底方案)。
  • 核心代碼示例
String[] arr = {"a", "b"};
// 錯(cuò)誤:固定長度List,無法修改
// List<String> list = Arrays.asList(arr);
// 正確:重新創(chuàng)建可修改ArrayList
List<String> list = new ArrayList<>(Arrays.asList(arr));
list.add("c"); // 正常執(zhí)行

二、受檢異常(Checked Exception)—— 外部環(huán)境異常,強(qiáng)制處理,資源釋放

繼承自java.lang.Exception(非RuntimeException子類),編譯期必須通過try-catch捕獲或throws聲明拋出,多由程序外部環(huán)境異常導(dǎo)致(如文件不存在、網(wǎng)絡(luò)斷開),核心處理原則是強(qiáng)制捕獲處理,核心操作是「釋放資源+業(yè)務(wù)兜底」。

1. IOException(及子類)—— IO操作核心異常(最常用)

  • 核心含義:所有IO操作的通用異常父類,子類覆蓋具體場景:FileNotFoundException(文件不存在)、SocketException(網(wǎng)絡(luò)斷開)、EOFException(文件提前結(jié)束)
  • 典型場景:文件讀寫、流的打開/關(guān)閉、網(wǎng)絡(luò)數(shù)據(jù)傳輸、控制臺(tái)輸入流操作
  • 標(biāo)準(zhǔn)處理方式(核心:保證IO資源100%釋放
    1. 優(yōu)雅方案:Java 7+ try-with-resources 語法(自動(dòng)關(guān)閉實(shí)現(xiàn)AutoCloseable接口的資源,替代finally,推薦);
    2. 傳統(tǒng)方案:try-catch-finally,在finally塊中手動(dòng)關(guān)閉資源(需判空,避免空指針);
    3. 業(yè)務(wù)兜底:捕獲異常后記錄日志,返回友好的業(yè)務(wù)提示(如“文件讀取失敗”),避免暴露底層異常。
  • 核心代碼示例(try-with-resources 自動(dòng)釋放資源,推薦)
// 流對象實(shí)現(xiàn)AutoCloseable,try代碼塊結(jié)束后自動(dòng)關(guān)閉,無需手動(dòng)finally
try (FileReader fr = new FileReader("test.txt");
     BufferedReader br = new BufferedReader(fr)) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (FileNotFoundException e) {
    System.err.println("業(yè)務(wù)提示:文件不存在,請檢查路徑");
    log.error("文件讀取失敗,路徑:test.txt", e); // 記錄詳細(xì)日志(含堆棧)
} catch (IOException e) {
    System.err.println("業(yè)務(wù)提示:文件讀取失敗");
    log.error("文件讀寫異常", e);
}
  • 關(guān)鍵子類FileNotFoundException(優(yōu)先捕獲,精準(zhǔn)定位文件問題)、SocketException(網(wǎng)絡(luò)IO,需增加重連邏輯)。

2. InterruptedException —— 線程中斷協(xié)作異常

  • 核心含義:線程處于可中斷阻塞狀態(tài)時(shí),被其他線程調(diào)用interrupt()中斷,是線程間的「協(xié)作中斷信號」(非錯(cuò)誤異常)
  • 典型場景:線程執(zhí)行Thread.sleep()/Object.wait()/CountDownLatch.await()/Thread.join()時(shí)被中斷
  • 關(guān)鍵特性:異常觸發(fā)后,JVM會(huì)自動(dòng)清除線程的中斷狀態(tài)isInterrupted()返回false),切勿空catch吞掉異常(并發(fā)編程大忌)
  • 標(biāo)準(zhǔn)處理方式(核心三原則:恢復(fù)狀態(tài)/釋放資源/優(yōu)雅終止,分3種場景)
    1. 工具方法場景:捕獲異常后恢復(fù)中斷狀態(tài)Thread.currentThread().interrupt())+ 向上拋出異常,讓上層調(diào)用方處理;
    2. 線程入口場景:捕獲異常后立即釋放資源(關(guān)閉流/釋放鎖)+ 直接終止線程(return);
    3. 批量任務(wù)場景:恢復(fù)中斷狀態(tài) + 跳過當(dāng)前任務(wù),讓后續(xù)代碼檢測到中斷并處理。
  • 核心代碼示例(工具方法+線程入口,最常用)
// 場景1:工具方法(不負(fù)責(zé)線程生命周期,向上拋出)
public void doBlockingWork() throws InterruptedException {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt(); // 恢復(fù)中斷狀態(tài),讓上層感知
        throw e; // 向上拋出
    }
}

// 場景2:線程入口(最終處理,釋放資源+終止)
Thread worker = new Thread(() -> {
    FileWriter writer = null;
    try {
        writer = new FileWriter("log.txt");
        doBlockingWork(); // 調(diào)用工具方法
    } catch (InterruptedException e) {
        System.out.println("收到中斷請求,開始優(yōu)雅終止");
        // 步驟1:釋放資源
        if (writer != null) {
            try { writer.close(); } catch (IOException ex) { log.error("資源釋放失敗", ex); }
        }
        // 步驟2:終止線程
        return;
    } catch (IOException e) {
        log.error("IO異常", e);
    }
});
worker.start();
worker.interrupt(); // 主線程觸發(fā)中斷

3. SQLException —— 數(shù)據(jù)庫JDBC操作專屬

  • 核心含義:執(zhí)行數(shù)據(jù)庫操作(增刪改查、連接、關(guān)閉)時(shí)觸發(fā),覆蓋連接失敗、SQL語法錯(cuò)誤、表/字段不存在等場景
  • 典型場景:數(shù)據(jù)庫地址/賬號密碼錯(cuò)誤、SQL語句拼寫錯(cuò)誤、操作不存在的表、連接池耗盡
  • 標(biāo)準(zhǔn)處理方式(核心:資源釋放+事務(wù)回滾+隱藏敏感信息
    1. 資源管理:使用try-with-resources自動(dòng)關(guān)閉Connection/Statement/ResultSet(均實(shí)現(xiàn)AutoCloseable),避免數(shù)據(jù)庫連接泄漏;
    2. 事務(wù)處理:異常時(shí)執(zhí)行事務(wù)回滾conn.rollback()),避免數(shù)據(jù)不一致;
    3. 日志與提示:記錄詳細(xì)日志(含SQL語句、參數(shù)),返回通用業(yè)務(wù)提示(如“數(shù)據(jù)庫操作失敗”),避免暴露數(shù)據(jù)庫地址/賬號等敏感信息;
    4. 重試機(jī)制:對連接超時(shí)、網(wǎng)絡(luò)抖動(dòng)等臨時(shí)異常,增加重試邏輯(配合Guava Retryer/Spring Retry)。
  • 核心代碼示例
String sql = "INSERT INTO user (name) VALUES (?)";
// try-with-resources 自動(dòng)關(guān)閉數(shù)據(jù)庫資源
try (Connection conn = DBUtil.getConnection();
     PreparedStatement pstmt = conn.prepareStatement(sql)) {
    conn.setAutoCommit(false); // 關(guān)閉自動(dòng)提交,開啟事務(wù)
    pstmt.setString(1, "test");
    pstmt.executeUpdate();
    conn.commit(); // 提交事務(wù)
} catch (SQLException e) {
    // 事務(wù)回滾
    if (conn != null) {
        try { conn.rollback(); } catch (SQLException ex) { log.error("事務(wù)回滾失敗", ex); }
    }
    log.error("SQL執(zhí)行失敗,SQL:{}", sql, e); // 記錄詳細(xì)日志
    System.err.println("業(yè)務(wù)提示:數(shù)據(jù)保存失敗,請稍后重試"); // 通用提示
}

4. ClassNotFoundException —— 類加載異常

  • 核心含義:JVM在類加載過程中,無法找到指定全限定名的類文件(包名+類名)
  • 典型場景:反射加載類時(shí)類名寫錯(cuò)(Class.forName("com.test.User"))、項(xiàng)目依賴缺失、classpath未包含該類
  • 標(biāo)準(zhǔn)處理方式
    1. 基礎(chǔ)排查:檢查類的全限定名是否拼寫正確(包名、類名大小寫);
    2. 環(huán)境檢查:確認(rèn)項(xiàng)目運(yùn)行時(shí)的classpath包含該類的class文件/依賴包;
    3. 異常處理:捕獲異常后記錄詳細(xì)日志(類名、classpath信息),返回明確的排查提示。
  • 核心代碼示例
try {
    Class<?> cls = Class.forName("com.test.User");
    Object obj = cls.newInstance();
} catch (ClassNotFoundException e) {
    log.error("類加載失敗,類名:com.test.User,請檢查類名/依賴", e);
    System.err.println("系統(tǒng)異常:類加載失敗,請聯(lián)系開發(fā)人員");
} catch (InstantiationException | IllegalAccessException e) {
    log.error("類實(shí)例化失敗", e);
}

5. ParseException —— 日期/字符串解析異常

  • 核心含義:對日期、自定義格式字符串進(jìn)行解析/格式化時(shí),輸入格式與指定格式不匹配
  • 典型場景SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); sdf.parse("2026/02/05")
  • 標(biāo)準(zhǔn)處理方式
    1. 根源規(guī)避:統(tǒng)一數(shù)據(jù)格式,前端傳參做格式限制(如日期僅允許yyyy-MM-dd);
    2. 優(yōu)雅方案:使用Java 8+ 新日期時(shí)間API(LocalDate/DateTimeFormatter),線程安全且拋出更友好的DateTimeParseException(運(yùn)行時(shí)異常);
    3. 異常捕獲:解析前校驗(yàn)輸入格式,捕獲異常后返回默認(rèn)值或友好提示。
  • 核心代碼示例(推薦新日期API,替代傳統(tǒng)SimpleDateFormat)
String dateStr = "2026/02/05";
// 傳統(tǒng)方式(SimpleDateFormat,非線程安全)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
    Date date = sdf.parse(dateStr);
} catch (ParseException e) {
    System.err.println("日期格式錯(cuò)誤,請按yyyy-MM-dd輸入");
}

// Java8+ 新日期API(推薦,線程安全,異常更友好)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
try {
    LocalDate date = LocalDate.parse(dateStr, formatter);
} catch (DateTimeParseException e) { // 運(yùn)行時(shí)異常,無需強(qiáng)制捕獲
    System.err.println("日期格式錯(cuò)誤,請按yyyy-MM-dd輸入");
}

三、JVM錯(cuò)誤(Error)—— 系統(tǒng)層面嚴(yán)重問題,提前規(guī)避,無需處理

繼承自java.lang.Error,屬于JVM/系統(tǒng)層面的嚴(yán)重異常,程序無法捕獲和恢復(fù),一旦發(fā)生通常導(dǎo)致程序崩潰,核心處理原則是提前規(guī)避,通過代碼優(yōu)化/JVM調(diào)優(yōu)/環(huán)境配置防止發(fā)生,無需在代碼中手動(dòng)捕獲。

1. OutOfMemoryError(OOM)—— 內(nèi)存溢出

  • 核心含義:JVM堆內(nèi)存、方法區(qū)、元空間等內(nèi)存區(qū)域耗盡,無法為新對象分配內(nèi)存
  • 典型場景:無限循環(huán)創(chuàng)建大對象、集合存儲(chǔ)大量數(shù)據(jù)未清理(內(nèi)存泄漏)、JVM堆內(nèi)存設(shè)置過小(-Xmx配置不合理)、靜態(tài)集合持有大量對象引用
  • 標(biāo)準(zhǔn)規(guī)避方式
    1. 代碼優(yōu)化:及時(shí)釋放無用對象引用(如集合使用后清空、避免靜態(tài)集合存儲(chǔ)業(yè)務(wù)數(shù)據(jù)),排查內(nèi)存泄漏(使用MAT/JProfiler工具);
    2. JVM調(diào)優(yōu):合理設(shè)置堆內(nèi)存參數(shù)(-Xms初始堆 = -Xmx最大堆,避免內(nèi)存頻繁擴(kuò)容,如-Xms2G -Xmx2G),調(diào)整元空間大?。?code>-XX:MetaspaceSize=256M);
    3. 業(yè)務(wù)優(yōu)化:采用分頁查詢/流式處理替代全量加載數(shù)據(jù),避免一次性將大量數(shù)據(jù)加載到內(nèi)存。

2. StackOverflowError —— 棧溢出

  • 核心含義:JVM方法調(diào)用棧的深度超過最大值,無限遞歸是最典型、最常見的場景
  • 典型場景:無限遞歸調(diào)用方法(public void test() { test(); })、方法調(diào)用鏈過長(多層級業(yè)務(wù)方法嵌套)
  • 標(biāo)準(zhǔn)規(guī)避方式
    1. 代碼優(yōu)化:杜絕無限遞歸,檢查遞歸方法的終止條件,確保能正常退出;若遞歸層級過深,改為循環(huán)實(shí)現(xiàn)(根本解決方案);
    2. 調(diào)優(yōu)輔助:調(diào)整JVM棧大小參數(shù)(-Xss,如-Xss1M),增大方法調(diào)用棧深度(謹(jǐn)慎使用,治標(biāo)不治本);
    3. 代碼重構(gòu):將過長的方法調(diào)用鏈拆分為多個(gè)獨(dú)立方法,減少嵌套層級。
  • 避坑點(diǎn):切勿依賴調(diào)整-Xss解決問題,無限遞歸即使增大棧大小,最終仍會(huì)觸發(fā)棧溢出。

3. NoClassDefFoundError —— 類定義未找到

  • 核心含義編譯期能找到類,但運(yùn)行期JVM無法找到該類的字節(jié)碼文件(與ClassNotFoundException的核心區(qū)別:前者是運(yùn)行期類加載失敗,后者是編譯/反射時(shí)類不存在)
  • 典型場景:編譯后刪除了類的class文件、依賴的第三方包編譯期存在但運(yùn)行期缺失、Maven/Gradle依賴包版本沖突
  • 標(biāo)準(zhǔn)規(guī)避方式
    1. 環(huán)境檢查:確認(rèn)項(xiàng)目運(yùn)行時(shí)的classpath包含所有依賴包,編譯后的class文件完整無缺失;
    2. 依賴管理:使用Maven/Gradle統(tǒng)一管理依賴,執(zhí)行clean install清理并重新編譯項(xiàng)目,避免依賴包缺失/沖突;
    3. 類加載器排查:避免自定義類加載器的加載范圍沖突,確保類被JVM正確加載。

四、Java 常見異常速查表(含核心處理方式,快速查閱)

分類異常名稱核心關(guān)鍵詞核心處理/規(guī)避方式
運(yùn)行時(shí)異常NullPointerException空對象、自動(dòng)拆箱Optional包裝/Objects非空校驗(yàn)/返回空對象而非null
ArrayIndexOutOfBoundsException數(shù)組索引越界增強(qiáng)for循環(huán)/索引前置校驗(yàn)/以length為邊界
IndexOutOfBoundsException集合/字符串索引越界非空校驗(yàn)/以size/length為邊界/Apache工具類輔助
ClassCastException強(qiáng)制類型轉(zhuǎn)換錯(cuò)誤instanceof判斷/Java14+模式匹配/集合指定泛型
InputMismatchExceptionScanner輸入類型不匹配hasNextXxx()前置判斷/清空輸入緩沖區(qū)/先讀字符串再轉(zhuǎn)換
ArithmeticException整數(shù)除零、非法算術(shù)運(yùn)算除數(shù)非零校驗(yàn)/try-catch兜底返回默認(rèn)值
IllegalArgumentException方法參數(shù)非法方法入口校驗(yàn)/主動(dòng)拋出異常/Spring注解校驗(yàn)
NumberFormatException字符串轉(zhuǎn)數(shù)值格式錯(cuò)誤NumberUtils工具類/正則校驗(yàn)/try-catch兜底
ConcurrentModificationException集合并發(fā)修改迭代器修改/線程安全集合/遍歷后統(tǒng)一修改
UnsupportedOperationException不支持的操作重新創(chuàng)建可修改集合/避免修改只讀集合
受檢異常IOException(及子類)文件/流/網(wǎng)絡(luò)IO操作try-with-resources自動(dòng)關(guān)資源/finally釋放/日志+業(yè)務(wù)提示
InterruptedException線程阻塞時(shí)被中斷恢復(fù)中斷狀態(tài)/釋放資源/優(yōu)雅終止/切勿吞異常
SQLException數(shù)據(jù)庫JDBC操作自動(dòng)關(guān)連接/事務(wù)回滾/詳細(xì)日志/通用業(yè)務(wù)提示
ClassNotFoundException反射/類加載找不到類檢查類名拼寫/確認(rèn)依賴完整/排查classpath
ParseException日期/字符串解析格式不匹配統(tǒng)一格式/Java8+新日期API/前置格式校驗(yàn)
JVM錯(cuò)誤OutOfMemoryError內(nèi)存溢出、OOM排查內(nèi)存泄漏/JVM堆調(diào)優(yōu)/分頁/流式處理/釋放無用引用
StackOverflowError棧溢出、無限遞歸杜絕無限遞歸/遞歸改循環(huán)/調(diào)整-Xss/拆分長調(diào)用鏈
NoClassDefFoundError運(yùn)行期找不到類定義檢查classpath/重新編譯項(xiàng)目/Maven/Gradle統(tǒng)一依賴管理

五、Java 異常處理通用最佳實(shí)踐(所有場景均適用)

  1. 切勿空catch吞掉異常:尤其是InterruptedException、IO異常、SQL異常,空catch會(huì)導(dǎo)致問題無法定位、資源泄漏、程序邏輯混亂;
  2. 異常處理粒度適中:不要用一個(gè)try-catch捕獲所有異常(如catch (Exception e)),按異常類型細(xì)分處理,便于精準(zhǔn)定位問題;
  3. 資源釋放是核心:涉及IO、數(shù)據(jù)庫、網(wǎng)絡(luò)連接等資源的操作,必須保證資源釋放(優(yōu)先使用try-with-resources);
  4. 日志記錄要完整:捕獲異常時(shí)記錄異常堆棧+業(yè)務(wù)上下文(如參數(shù)、SQL語句),避免僅打印e.printStackTrace();
  5. 前端/用戶提示要友好:隱藏底層異常細(xì)節(jié)(如數(shù)據(jù)庫地址、SQL語句),返回通用的業(yè)務(wù)提示(如“操作失敗,請稍后重試”);
  6. 運(yùn)行時(shí)異常以預(yù)防為主:通過判空、參數(shù)校驗(yàn)、索引檢查等邏輯從根源避免,而非依賴try-catch;
  7. 自定義異常語義清晰:復(fù)雜業(yè)務(wù)中自定義異常(繼承Exception/RuntimeException),讓異常更貼合業(yè)務(wù)場景(如UserNotExistException),便于統(tǒng)一處理。
  8. 運(yùn)行時(shí)異常:重點(diǎn)在「預(yù)防」,通過嚴(yán)謹(jǐn)?shù)拇a邏輯(判空、參數(shù)校驗(yàn)、索引檢查、泛型使用)避免,是日常bug排查的主要對象;
  9. 受檢異常:重點(diǎn)在「處理」,編譯期強(qiáng)制捕獲/拋出,需根據(jù)業(yè)務(wù)場景做兜底(如IO異常關(guān)閉流、SQL異?;貪L事務(wù));
  10. Error:重點(diǎn)在「規(guī)避」,通過合理的JVM參數(shù)配置(如調(diào)整堆內(nèi)存)、優(yōu)化代碼(避免無限遞歸)防止,程序無法處理;
  11. 異常處理原則:切勿空catch吞掉異常(尤其是InterruptedException),異常處理的核心是「恢復(fù)狀態(tài)、釋放資源、優(yōu)雅提示/終止」。

掌握以上異常的處理方式和通用原則,能大幅提升Java代碼的健壯性和可維護(hù)性,快速定位并解決開發(fā)中的各類異常問題,同時(shí)避免因異常處理不當(dāng)導(dǎo)致的資源泄漏、程序崩潰、數(shù)據(jù)不一致等嚴(yán)重問題。

總結(jié)

到此這篇關(guān)于Java常見異常全面梳理的文章就介紹到這了,更多相關(guān)Java常見異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Java連接WMI獲取系統(tǒng)信息的方法

    使用Java連接WMI獲取系統(tǒng)信息的方法

    在 Windows 系統(tǒng)上,WMI是一套管理數(shù)據(jù)和操作系統(tǒng)組件的基礎(chǔ)設(shè)施,能讓應(yīng)用程序查詢系統(tǒng)信息、監(jiān)控硬件狀態(tài)以及管理系統(tǒng)配置,本項(xiàng)目旨在講解如何通過 Java 連接 WMI 獲取系統(tǒng)信息,需要的朋友可以參考下
    2025-03-03
  • 解決Unboxing of'stringRedisTemplate.hasKey(xx)'may produce 'NullPointerException' 警告問題

    解決Unboxing of'stringRedisTemplate.hasKey(xx)'

    文章介紹了在使用`stringRedisTemplate.hasKey(xx)`方法時(shí)可能會(huì)出現(xiàn)`NullPointerException`警告的原因,并提出了相應(yīng)的解決方法
    2026-03-03
  • JavaFX桌面應(yīng)用未響應(yīng)問題解決方案

    JavaFX桌面應(yīng)用未響應(yīng)問題解決方案

    這篇文章主要介紹了JavaFX桌面應(yīng)用未響應(yīng)問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java源碼解析之ConcurrentHashMap

    Java源碼解析之ConcurrentHashMap

    今天帶大家分析Java源碼,文中對Java ConcurrentHashMap介紹的非常詳細(xì),有代碼示例,對正在學(xué)習(xí)Java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • 詳解FileInputStream讀取文件數(shù)據(jù)的兩種方式

    詳解FileInputStream讀取文件數(shù)據(jù)的兩種方式

    這篇文章主要介紹了詳解FileInputStream讀取文件數(shù)據(jù)的兩種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java線程池的優(yōu)點(diǎn)及池化技術(shù)的應(yīng)用

    Java線程池的優(yōu)點(diǎn)及池化技術(shù)的應(yīng)用

    這篇文章主要介紹了Java線程池的優(yōu)點(diǎn)及池化技術(shù)的應(yīng)用,Java種提高程序的執(zhí)行效率有兩種實(shí)現(xiàn)方法,一個(gè)是使用線程、另一個(gè)是使用線程池,下文我們就來具體介紹該詳細(xì)內(nèi)容吧,需要的小伙伴可以參考一下
    2022-05-05
  • Java如何實(shí)現(xiàn)讀取txt文件內(nèi)容并生成Word文檔

    Java如何實(shí)現(xiàn)讀取txt文件內(nèi)容并生成Word文檔

    本文主要介紹了通過Java實(shí)現(xiàn)讀取txt文件中的內(nèi)容,并將內(nèi)容生成Word文檔。文章的代碼非常詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2021-12-12
  • java 使用POI合并兩個(gè)word文檔

    java 使用POI合并兩個(gè)word文檔

    這篇文章主要介紹了java 使用POI合并兩個(gè)word文檔的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring Boot 3.0升級指南

    Spring Boot 3.0升級指南

    這篇文章主要為大家介紹了Spring Boot 3.0升級指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • java Quartz定時(shí)器任務(wù)與Spring task定時(shí)的幾種實(shí)現(xiàn)方法

    java Quartz定時(shí)器任務(wù)與Spring task定時(shí)的幾種實(shí)現(xiàn)方法

    本篇文章主要介紹了java Quartz定時(shí)器任務(wù)與Spring task定時(shí)的幾種實(shí)現(xiàn)方法的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-02-02

最新評論

呼图壁县| 达拉特旗| 博野县| 紫金县| 临邑县| 吐鲁番市| 五家渠市| 武宁县| 广平县| 黔西县| 银川市| 疏附县| 武穴市| 南昌县| 宜州市| 大洼县| 兴和县| 湘西| 赫章县| 荣昌县| 礼泉县| 西昌市| 辰溪县| 荆州市| 临西县| 错那县| 无棣县| 子长县| 剑川县| 开封县| 茌平县| 藁城市| 两当县| 安达市| 永川市| 阿拉尔市| 犍为县| 马龙县| 山东省| 汽车| 饶平县|