Java 常见异常梳理

Java 常见异常全面梳理(分类+含义+典型场景)

Java 异常体系核心分为 运行时异常(RuntimeException,非受检)编译时异常(Checked Exception 受检),前者编译期无需强制捕获,由程序逻辑错误导致;后者编译期必须显式捕获/抛出,由外部环境(如IO、网络、输入)异常导致。此外,还有错误(Error) 属于JVM层面严重问题,通常无需程序处理。
区分「运行时异常(预防为主)、受检异常(强制处理)、JVM错误(提前规避)」

在这里插入图片描述

一、运行时异常(RuntimeException)—— 逻辑错误主导,预防优先,捕获兜底

继承自java.lang.RuntimeException,编译期无需强制处理,多由代码逻辑不严谨导致,核心处理原则是通过严谨的代码逻辑从根源避免,仅对无法预防的场景做捕获兜底

1. NullPointerException(NPE)—— 开发最高频异常

  • 核心含义:调用空对象的方法/属性、对空对象执行集合/数组操作,或自动拆箱空包装类
  • 典型场景Object obj = null; obj.toString();Integer num = null; int n = num;、方法返回null未判空直接使用
  • 标准处理方式(按优雅度排序,从基础到高级)
    1. 基础方案:显式判空,对所有可能为null的对象执行非空校验;
    2. 优雅方案:Java 8+ Optional类,包装可能为null的对象,避免手动判空;
    3. 校验方案:使用Objects.requireNonNull()做参数/对象非空校验,快速定位空指针源头;
    4. 开发规范:方法返回值尽量返回空集合/空对象(如Collections.emptyList()),而非null,减少调用方判空成本。
  • 核心代码示例
// 1. 显式判空Object obj =getObj();if(obj !=null){ obj.toString();}// 2. Optional优雅处理(推荐,无嵌套判空)Optional.ofNullable(getObj()).ifPresent(o -> o.toString());// 仅当非空时执行String res =Optional.ofNullable(getStr()).orElse("默认值");// 空则返回默认值// 3. 非空校验(参数/方法内对象,快速定位问题)publicvoiddoWork(User user){Objects.requireNonNull(user,"用户对象不能为空");Objects.requireNonNull(user.getName(),"用户名不能为空");}
  • 避坑点:切勿仅用if (obj != null)做多层嵌套判空(会导致代码臃肿),优先使用Optional。

2. ArrayIndexOutOfBoundsException —— 数组操作专属

  • 核心含义:访问数组的索引超出有效范围(索引<0 或 索引>=数组长度)
  • 典型场景int[] arr = new int[3]; arr[3] = 10;、循环遍历数组时条件写为i <= arr.length
  • 标准处理方式
    1. 核心原则:遍历数组始终以arr.length为边界,循环条件用i < arr.length
    2. 根源规避:使用增强for循环遍历数组,无需手动操作索引,从源头避免越界;
    3. 前置校验:手动操作索引时,先校验索引合法性(index >= 0 && index < arr.length)。
  • 核心代码示例
int[] arr ={1,2,3};// 1. 增强for循环(推荐,无索引操作)for(int num : arr){System.out.println(num);}// 2. 手动索引操作(前置校验)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)

  • 核心含义:访问集合/字符串的索引超出有效范围,是数组越界的「集合/字符串版」
  • 典型场景List<String> list = new ArrayList<>(); list.get(0);"java".substring(5)
  • 标准处理方式
    1. 集合操作:遍历用增强for循环,手动获取元素前校验index < list.size()+集合非空(!list.isEmpty());
    2. 字符串操作:截取/获取字符前校验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工具类,越界会返回空/原字符串,无异常)String sub =StringUtils.substring(str,0, index);

4. ClassCastException —— 类型转换高频异常

  • 核心含义:将对象强制转换为其实际运行时类型并非所属的类/接口(无继承/实现关系)
  • 典型场景Object obj = new Integer(10); String str = (String) obj;、泛型擦除后集合强转元素
  • 标准处理方式
    1. 前置判断:转换前用instanceof校验对象实际运行时类型,再执行强转;
    2. 简化方案:Java 14+ 模式匹配,一步完成「类型判断+强制转换」,简化代码;
    3. 根源规避:集合操作强制指定泛型(如List<String> list = new ArrayList<>()),编译期拦截非目标类型元素。
  • 核心代码示例
Object obj =newInteger(10);// 1. 传统方式:instanceof判断+强转if(obj instanceofString){String str =(String) obj;}// 2. Java14+ 模式匹配(推荐,少一层代码)if(obj instanceofString str){System.out.println(str.length());}// 3. 泛型规避(从根源避免)List<String> list =newArrayList<>(); list.add("java");// list.add(10); // 编译期直接报错,无法添加非String类型

5. InputMismatchException —— Scanner输入专属

  • 核心含义java.util.Scanner读取数据时,输入数据类型与预期读取类型不兼容
  • 典型场景:用scanner.nextInt()读整数,用户输入字符串(“abc”)、小数(3.14)
  • 标准处理方式(核心:清空输入缓冲区,避免死循环
    1. 推荐方案:先判断再读取,使用Scanner的hasNextXxx()系列方法匹配读取方法(hasNextInt()对应nextInt());
    2. 兜底方案:捕获异常后,必须调用scanner.next()清空缓冲区的无效数据;
    3. 万能方案:先读取原始字符串,再通过包装类手动转换,配合try-catch处理。
  • 核心代码示例(推荐方案,无异常)
Scanner scanner =newScanner(System.in);int num =0;while(true){System.out.print("请输入整数:");if(scanner.hasNextInt()){ num = scanner.nextInt();break;// 输入合法,退出循环}else{System.err.println("输入错误,仅支持整数!"); scanner.next();// 关键:清空缓冲区的无效数据,避免死循环}}

6. ArithmeticException —— 数值计算错误

  • 核心含义:算术运算中出现非法操作,整数除零/取模模数为0是最典型场景
  • 典型场景int a = 10 / 0;10 % 0(注:浮点数除零结果为Infinity,不会触发此异常)
  • 标准处理方式
    1. 前置校验:对除法/取模的除数/模数做非零校验,从根源避免;
    2. 异常兜底:捕获异常后,根据业务返回默认值或抛出自定义提示,避免程序崩溃。
  • 核心代码示例
int a =10, b =0;int res =0;// 前置校验(推荐)if(b !=0){ res = a / b;}else{System.err.println("除数不能为零"); res =0;// 业务默认值}// 异常兜底(无法提前校验的场景)try{ res = a / b;}catch(ArithmeticException e){System.err.println("计算失败:除数不能为零"); res =0;}

7. IllegalArgumentException —— 参数非法通用异常

  • 核心含义:方法接收到不符合业务要求的非法参数,是自定义方法参数校验的标准异常
  • 典型场景:方法要求参数>0却传入-1、要求非空字符串却传入空串、Collections.sort(null)
  • 标准处理方式
    1. 主动抛出:方法入口处做参数校验,参数不合法时主动抛出该异常,并携带明确的错误提示;
    2. 工具辅助:使用Objects/Apache Commons工具类简化参数校验,避免重复代码;
    3. 框架适配:Spring项目可使用@Valid/@NotBlank等注解做参数自动校验,无需手动判断。
  • 核心代码示例
// 手动参数校验+主动抛出异常(推荐,语义清晰)publicvoidsetAge(int age){if(age <0|| age >150){thrownewIllegalArgumentException("年龄必须在0-150之间,当前值:"+ age);}this.age = age;}// Spring项目注解校验(简化代码)publicvoidaddUser(@ValidUser user){// User类中:@NotBlank(message = "用户名不能为空") private String name;}

8. NumberFormatException —— 数值格式转换错误

  • 核心含义:将非数值格式的字符串转换为int/double/long等数值类型时触发
  • 典型场景Integer.parseInt("123a");Double.parseDouble("3.14.5");、前端传参非数值字符串后端直接转换
  • 标准处理方式
    1. 异常捕获:转换时通过try-catch捕获异常,返回业务默认值或提示格式错误;
    2. 工具辅助:使用org.apache.commons.lang3.math.NumberUtils,转换失败返回默认值,无需手动捕获;
    3. 前置校验:转换前通过正则表达式校验字符串是否为合法数值(如^\\d+$匹配整数)。
  • 核心代码示例
String str ="123a";// 1. try-catch兜底int num1 =0;try{ num1 =Integer.parseInt(str);}catch(NumberFormatException e){System.err.println("数值格式错误,默认值为0");}// 2. NumberUtils工具类(推荐,简化代码)int num2 =NumberUtils.toInt(str,0);// 转换失败返回默认值0double num3 =NumberUtils.toDouble(str,0.0);

9. ConcurrentModificationException —— 集合并发修改错误

  • 核心含义:单/多线程中,遍历集合的同时执行结构性修改(增/删/修改集合容量)
  • 典型场景:增强for循环遍历List时调用list.remove()、多线程同时操作非线程安全集合(ArrayList/HashMap)
  • 标准处理方式(分单/多线程场景)
    1. 单线程:使用迭代器(Iterator) 遍历并修改,调用it.remove(),这是集合遍历修改的标准方式;
    2. 多线程:替换为线程安全集合CopyOnWriteArrayList替代ArrayList、ConcurrentHashMap替代HashMap);
    3. 兜底方案:遍历前将集合转为数组,或遍历过程中收集需要修改的元素,遍历完成后统一处理
  • 核心代码示例
List<String> list =newArrayList<>(); 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();// 无异常,标准方式}}// 2. 多线程安全集合(直接替换,无需修改业务代码)List<String> safeList =newCopyOnWriteArrayList<>();Map<String,String> safeMap =newConcurrentHashMap<>();

10. UnsupportedOperationException —— 不支持的操作

  • 核心含义:调用了对象未实现/不支持的方法,多为只读/固定长度对象的修改操作
  • 典型场景Arrays.asList(arr).add(1);(该List为固定长度)、对Collections.unmodifiableList()执行增删
  • 标准处理方式
    1. 根源规避:若需修改数组转换的List,重新创建可修改集合new ArrayList<>(Arrays.asList(arr)));
    2. 开发规范:使用集合前确认其类型,避免对只读集合执行修改操作;
    3. 前置判断:通过集合的class判断是否为可修改类型(兜底方案)。
  • 核心代码示例
String[] arr ={"a","b"};// 错误:固定长度List,无法修改// List<String> list = Arrays.asList(arr);// 正确:重新创建可修改ArrayListList<String> list =newArrayList<>(Arrays.asList(arr)); list.add("c");// 正常执行

二、受检异常(Checked Exception)—— 外部环境异常,强制处理,资源释放

继承自java.lang.Exception(非RuntimeException子类),编译期必须通过try-catch捕获或throws声明抛出,多由程序外部环境异常导致(如文件不存在、网络断开),核心处理原则是强制捕获处理,核心操作是「释放资源+业务兜底」

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

  • 核心含义:所有IO操作的通用异常父类,子类覆盖具体场景:FileNotFoundException(文件不存在)、SocketException(网络断开)、EOFException(文件提前结束)
  • 典型场景:文件读写、流的打开/关闭、网络数据传输、控制台输入流操作
  • 标准处理方式(核心:保证IO资源100%释放
    1. 优雅方案:Java 7+ try-with-resources 语法(自动关闭实现AutoCloseable接口的资源,替代finally,推荐);
    2. 传统方案:try-catch-finally,在finally块中手动关闭资源(需判空,避免空指针);
    3. 业务兜底:捕获异常后记录日志,返回友好的业务提示(如“文件读取失败”),避免暴露底层异常。
  • 核心代码示例(try-with-resources 自动释放资源,推荐)
// 流对象实现AutoCloseable,try代码块结束后自动关闭,无需手动finallytry(FileReader fr =newFileReader("test.txt");BufferedReader br =newBufferedReader(fr)){String line;while((line = br.readLine())!=null){System.out.println(line);}}catch(FileNotFoundException e){System.err.println("业务提示:文件不存在,请检查路径"); log.error("文件读取失败,路径:test.txt", e);// 记录详细日志(含堆栈)}catch(IOException e){System.err.println("业务提示:文件读取失败"); log.error("文件读写异常", e);}
  • 关键子类FileNotFoundException(优先捕获,精准定位文件问题)、SocketException(网络IO,需增加重连逻辑)。

2. InterruptedException —— 线程中断协作异常

  • 核心含义:线程处于可中断阻塞状态时,被其他线程调用interrupt()中断,是线程间的「协作中断信号」(非错误异常)
  • 典型场景:线程执行Thread.sleep()/Object.wait()/CountDownLatch.await()/Thread.join()时被中断
  • 关键特性:异常触发后,JVM会自动清除线程的中断状态isInterrupted()返回false),切勿空catch吞掉异常(并发编程大忌)
  • 标准处理方式(核心三原则:恢复状态/释放资源/优雅终止,分3种场景)
    1. 工具方法场景:捕获异常后恢复中断状态Thread.currentThread().interrupt())+ 向上抛出异常,让上层调用方处理;
    2. 线程入口场景:捕获异常后立即释放资源(关闭流/释放锁)+ 直接终止线程(return);
    3. 批量任务场景:恢复中断状态 + 跳过当前任务,让后续代码检测到中断并处理。
  • 核心代码示例(工具方法+线程入口,最常用)
// 场景1:工具方法(不负责线程生命周期,向上抛出)publicvoiddoBlockingWork()throwsInterruptedException{try{Thread.sleep(5000);}catch(InterruptedException e){Thread.currentThread().interrupt();// 恢复中断状态,让上层感知throw e;// 向上抛出}}// 场景2:线程入口(最终处理,释放资源+终止)Thread worker =newThread(()->{FileWriter writer =null;try{ writer =newFileWriter("log.txt");doBlockingWork();// 调用工具方法}catch(InterruptedException e){System.out.println("收到中断请求,开始优雅终止");// 步骤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();// 主线程触发中断

3. SQLException —— 数据库JDBC操作专属

  • 核心含义:执行数据库操作(增删改查、连接、关闭)时触发,覆盖连接失败、SQL语法错误、表/字段不存在等场景
  • 典型场景:数据库地址/账号密码错误、SQL语句拼写错误、操作不存在的表、连接池耗尽
  • 标准处理方式(核心:资源释放+事务回滚+隐藏敏感信息
    1. 资源管理:使用try-with-resources自动关闭Connection/Statement/ResultSet(均实现AutoCloseable),避免数据库连接泄漏;
    2. 事务处理:异常时执行事务回滚conn.rollback()),避免数据不一致;
    3. 日志与提示:记录详细日志(含SQL语句、参数),返回通用业务提示(如“数据库操作失败”),避免暴露数据库地址/账号等敏感信息;
    4. 重试机制:对连接超时、网络抖动等临时异常,增加重试逻辑(配合Guava Retryer/Spring Retry)。
  • 核心代码示例
String sql ="INSERT INTO user (name) VALUES (?)";// try-with-resources 自动关闭数据库资源try(Connection conn =DBUtil.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)){ conn.setAutoCommit(false);// 关闭自动提交,开启事务 pstmt.setString(1,"test"); pstmt.executeUpdate(); conn.commit();// 提交事务}catch(SQLException e){// 事务回滚if(conn !=null){try{ conn.rollback();}catch(SQLException ex){ log.error("事务回滚失败", ex);}} log.error("SQL执行失败,SQL:{}", sql, e);// 记录详细日志System.err.println("业务提示:数据保存失败,请稍后重试");// 通用提示}

4. ClassNotFoundException —— 类加载异常

  • 核心含义:JVM在类加载过程中,无法找到指定全限定名的类文件(包名+类名)
  • 典型场景:反射加载类时类名写错(Class.forName("com.test.User"))、项目依赖缺失、classpath未包含该类
  • 标准处理方式
    1. 基础排查:检查类的全限定名是否拼写正确(包名、类名大小写);
    2. 环境检查:确认项目运行时的classpath包含该类的class文件/依赖包;
    3. 异常处理:捕获异常后记录详细日志(类名、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("系统异常:类加载失败,请联系开发人员");}catch(InstantiationException|IllegalAccessException e){ log.error("类实例化失败", e);}

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

  • 核心含义:对日期、自定义格式字符串进行解析/格式化时,输入格式与指定格式不匹配
  • 典型场景SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); sdf.parse("2026/02/05")
  • 标准处理方式
    1. 根源规避:统一数据格式,前端传参做格式限制(如日期仅允许yyyy-MM-dd);
    2. 优雅方案:使用Java 8+ 新日期时间API(LocalDate/DateTimeFormatter),线程安全且抛出更友好的DateTimeParseException(运行时异常);
    3. 异常捕获:解析前校验输入格式,捕获异常后返回默认值或友好提示。
  • 核心代码示例(推荐新日期API,替代传统SimpleDateFormat)
String dateStr ="2026/02/05";// 传统方式(SimpleDateFormat,非线程安全)SimpleDateFormat sdf =newSimpleDateFormat("yyyy-MM-dd");try{Date date = sdf.parse(dateStr);}catch(ParseException e){System.err.println("日期格式错误,请按yyyy-MM-dd输入");}// Java8+ 新日期API(推荐,线程安全,异常更友好)DateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyy-MM-dd");try{LocalDate date =LocalDate.parse(dateStr, formatter);}catch(DateTimeParseException e){// 运行时异常,无需强制捕获System.err.println("日期格式错误,请按yyyy-MM-dd输入");}

三、JVM错误(Error)—— 系统层面严重问题,提前规避,无需处理

继承自java.lang.Error,属于JVM/系统层面的严重异常,程序无法捕获和恢复,一旦发生通常导致程序崩溃,核心处理原则是提前规避,通过代码优化/JVM调优/环境配置防止发生,无需在代码中手动捕获

1. OutOfMemoryError(OOM)—— 内存溢出

  • 核心含义:JVM堆内存、方法区、元空间等内存区域耗尽,无法为新对象分配内存
  • 典型场景:无限循环创建大对象、集合存储大量数据未清理(内存泄漏)、JVM堆内存设置过小(-Xmx配置不合理)、静态集合持有大量对象引用
  • 标准规避方式
    1. 代码优化:及时释放无用对象引用(如集合使用后清空、避免静态集合存储业务数据),排查内存泄漏(使用MAT/JProfiler工具);
    2. JVM调优:合理设置堆内存参数(-Xms初始堆 = -Xmx最大堆,避免内存频繁扩容,如-Xms2G -Xmx2G),调整元空间大小(-XX:MetaspaceSize=256M);
    3. 业务优化:采用分页查询/流式处理替代全量加载数据,避免一次性将大量数据加载到内存。

2. StackOverflowError —— 栈溢出

  • 核心含义:JVM方法调用栈的深度超过最大值,无限递归是最典型、最常见的场景
  • 典型场景:无限递归调用方法(public void test() { test(); })、方法调用链过长(多层级业务方法嵌套)
  • 标准规避方式
    1. 代码优化:杜绝无限递归,检查递归方法的终止条件,确保能正常退出;若递归层级过深,改为循环实现(根本解决方案);
    2. 调优辅助:调整JVM栈大小参数(-Xss,如-Xss1M),增大方法调用栈深度(谨慎使用,治标不治本);
    3. 代码重构:将过长的方法调用链拆分为多个独立方法,减少嵌套层级。
  • 避坑点:切勿依赖调整-Xss解决问题,无限递归即使增大栈大小,最终仍会触发栈溢出。

3. NoClassDefFoundError —— 类定义未找到

  • 核心含义编译期能找到类,但运行期JVM无法找到该类的字节码文件(与ClassNotFoundException的核心区别:前者是运行期类加载失败,后者是编译/反射时类不存在)
  • 典型场景:编译后删除了类的class文件、依赖的第三方包编译期存在但运行期缺失、Maven/Gradle依赖包版本冲突
  • 标准规避方式
    1. 环境检查:确认项目运行时的classpath包含所有依赖包,编译后的class文件完整无缺失;
    2. 依赖管理:使用Maven/Gradle统一管理依赖,执行clean install清理并重新编译项目,避免依赖包缺失/冲突;
    3. 类加载器排查:避免自定义类加载器的加载范围冲突,确保类被JVM正确加载。

四、Java 常见异常速查表(含核心处理方式,快速查阅)

分类异常名称核心关键词核心处理/规避方式
运行时异常NullPointerException空对象、自动拆箱Optional包装/Objects非空校验/返回空对象而非null
ArrayIndexOutOfBoundsException数组索引越界增强for循环/索引前置校验/以length为边界
IndexOutOfBoundsException集合/字符串索引越界非空校验/以size/length为边界/Apache工具类辅助
ClassCastException强制类型转换错误instanceof判断/Java14+模式匹配/集合指定泛型
InputMismatchExceptionScanner输入类型不匹配hasNextXxx()前置判断/清空输入缓冲区/先读字符串再转换
ArithmeticException整数除零、非法算术运算除数非零校验/try-catch兜底返回默认值
IllegalArgumentException方法参数非法方法入口校验/主动抛出异常/Spring注解校验
NumberFormatException字符串转数值格式错误NumberUtils工具类/正则校验/try-catch兜底
ConcurrentModificationException集合并发修改迭代器修改/线程安全集合/遍历后统一修改
UnsupportedOperationException不支持的操作重新创建可修改集合/避免修改只读集合
受检异常IOException(及子类)文件/流/网络IO操作try-with-resources自动关资源/finally释放/日志+业务提示
InterruptedException线程阻塞时被中断恢复中断状态/释放资源/优雅终止/切勿吞异常
SQLException数据库JDBC操作自动关连接/事务回滚/详细日志/通用业务提示
ClassNotFoundException反射/类加载找不到类检查类名拼写/确认依赖完整/排查classpath
ParseException日期/字符串解析格式不匹配统一格式/Java8+新日期API/前置格式校验
JVM错误OutOfMemoryError内存溢出、OOM排查内存泄漏/JVM堆调优/分页/流式处理/释放无用引用
StackOverflowError栈溢出、无限递归杜绝无限递归/递归改循环/调整-Xss/拆分长调用链
NoClassDefFoundError运行期找不到类定义检查classpath/重新编译项目/Maven/Gradle统一依赖管理

五、Java 异常处理通用最佳实践(所有场景均适用)

  1. 切勿空catch吞掉异常:尤其是InterruptedException、IO异常、SQL异常,空catch会导致问题无法定位、资源泄漏、程序逻辑混乱;
  2. 异常处理粒度适中:不要用一个try-catch捕获所有异常(如catch (Exception e)),按异常类型细分处理,便于精准定位问题;
  3. 资源释放是核心:涉及IO、数据库、网络连接等资源的操作,必须保证资源释放(优先使用try-with-resources);
  4. 日志记录要完整:捕获异常时记录异常堆栈+业务上下文(如参数、SQL语句),避免仅打印e.printStackTrace()
  5. 前端/用户提示要友好:隐藏底层异常细节(如数据库地址、SQL语句),返回通用的业务提示(如“操作失败,请稍后重试”);
  6. 运行时异常以预防为主:通过判空、参数校验、索引检查等逻辑从根源避免,而非依赖try-catch;
  7. 自定义异常语义清晰:复杂业务中自定义异常(继承Exception/RuntimeException),让异常更贴合业务场景(如UserNotExistException),便于统一处理。
  8. 运行时异常:重点在「预防」,通过严谨的代码逻辑(判空、参数校验、索引检查、泛型使用)避免,是日常bug排查的主要对象;
  9. 受检异常:重点在「处理」,编译期强制捕获/抛出,需根据业务场景做兜底(如IO异常关闭流、SQL异常回滚事务);
  10. Error:重点在「规避」,通过合理的JVM参数配置(如调整堆内存)、优化代码(避免无限递归)防止,程序无法处理;
  11. 异常处理原则:切勿空catch吞掉异常(尤其是InterruptedException),异常处理的核心是「恢复状态、释放资源、优雅提示/终止」。

掌握以上异常的处理方式和通用原则,能大幅提升Java代码的健壮性和可维护性,快速定位并解决开发中的各类异常问题,同时避免因异常处理不当导致的资源泄漏、程序崩溃、数据不一致等严重问题。

Read more

【C++】深入浅出“图”——最短路径算法

【C++】深入浅出“图”——最短路径算法

文章目录 * 一、Dijkstra算法 * 二、Bellman_Ford算法 * 三、Floyd_Warshall算法 一、Dijkstra算法 最短路径问题是指,从在带权的有向图中从某一顶点出发,找到通往另一顶点的最短路径,“最短”指的是沿路径各边的权值总和最小。 Dijkstra算法是单源最短路径的经典贪心算法,只能用于没有负权的图。它从起点出发,每次选当前距离最小且未确定最短路径的节点,用它去松弛(更新)所有邻接点的最短路径估计值,标记该节点为 “已确定”,重复此过程直到所有节点处理完毕,最终得到起点到图中所有节点的最短路径。 // src是选定的起点,dist记录起点到各点的最短路径,pPath记录到每个点的最短路径的前驱顶点下标voidDijkstra(const V& src, vector<W>& dist, vector<int>& pPath){ size_t srci =GetVertexIndex(

By Ne0inhk
深入解剖STL RB-tree(红黑树):用图解带入相关复杂操作实现

深入解剖STL RB-tree(红黑树):用图解带入相关复杂操作实现

👇点击进入作者专栏: 《算法画解》 ✅ 《linux系统编程》✅ 《C++》 ✅ 文章目录 * 一、红黑树介绍 * 1. 什么是红黑树? * 2. 红黑树的规则 * 3. 为什么最长路径不超过最短路径的两倍? * 4. 红黑树的效率 * 二、红黑树的实现 * 2.1 红黑树的节点结构 * 2.2 红黑树整体结构 * 三、红黑树的插入操作 * 3.1 插入的大致流程 * 3.2 插入后的三种情况 * 情况1:叔叔节点存在且为红色(变色处理) * 情况2:叔叔节点不存在或为黑色 + cur和p在同一侧(单旋+变色) * 情况3:叔叔节点不存在或为黑色 + cur和p在不同侧(双旋+变色) * 3.3 插入完整代码 * 3.4 旋转操作的实现

By Ne0inhk
C++之基于正倒排索引的Boost搜索引擎项目usuallytool部分代码及详解

C++之基于正倒排索引的Boost搜索引擎项目usuallytool部分代码及详解

这部分是通用工具部分的代码,简单来说就是这份代码里面的函数会在项目的其他多个部分里面被使用,所以我们专门创建一个部分用来存储这些代码。 1.FileUtil 这个类就是专门用来读取文件用的,这个代码从指定的文件路径读取文件内容,将读取到的内容(按行读取)追加到传入的字符串指针(out)所指向的字符串中;同时,该方法会返回一个布尔值,用于标识读取操作是否成功 —— 若文件成功打开并完成读取,返回 true;若文件打开失败(如路径错误等),则输出错误信息并返回 false。 文件以二进制输入模式打开,读取过程中不会修改原文件内容。 class FileUtil{ public: static bool ReadFile(const std::string &file_path,std::string *out) { //下面这行代码就是在打开文件,并通过ifstream定义一个对象in,用于关联特定的文件 std::ifstream in(file_path,std::ios::in

By Ne0inhk