《Java 100 天进阶之路》第35篇:Java异常处理最佳实践

java学习之路-异常处理机制 本文章学习内容:介绍什么是异常、异常的分类、常见的异常有哪些、异常发生是是如何处理的、自定义异常类型。 阅读详情

第35篇:Java异常处理最佳实践

📌 系列导航:《Java 100 天进阶之路》完整目录 |
⬅️ 上一篇:第34篇:Java序列化与反序列化详解 |
➡️ 下一篇:第36篇:选择最适合自己的NIO,一探流技术


一、核心知识点

  • 异常处理的基本原则:只捕获能处理的异常,不要捕获后什么都不做
  • 检查型异常与运行时异常的使用场景
  • try-catch-finally 的正确用法
  • try-with-resources(自动关闭资源)
  • 自定义异常的规范
  • 异常链与异常包装
  • 日志记录的最佳实践

二、通俗讲解(1分钟开心学)

1. 异常处理的核心思想

  • 只捕获你能处理的异常。
  • 捕获后要做出有意义的响应(记录日志、返回默认值、重试、包装后重新抛出)。

2. 检查型异常 vs 运行时异常

  • 检查型异常(如 IOException):调用者必须处理或声明抛出,代表可恢复的外部错误(文件不存在、网络中断)。
  • 运行时异常(如 NullPointerException):不强制处理,代表编程错误(参数校验不足、数组越界),应当通过改进代码避免。

3. try-with-resources

自动关闭实现了 AutoCloseable 接口的资源(文件、网络连接、数据库连接),避免 finally 中手动关闭的繁琐。

4. 异常链

当你在一个异常中包装另一个异常时,可以保留原始异常信息,便于排查。

5. 日志记录

捕获异常后务必记录日志(使用 log.error("消息", e)),不要只打印 e.printStackTrace()(在正式环境可能不可见)。

6. 自定义异常

  • 继承 Exception(检查型)或 RuntimeException(运行时)。
  • 提供多个构造方法(无参、带消息、带消息+原异常)。

生活类比:
异常处理就像开车遇到故障。能自己修的小毛病(运行时异常)就用工具修好(改进代码)。大问题(检查型异常)需要呼叫救援(try-catch),然后记录事故(日志)。

三、实操代码案例 + 场景说明

场景:读取配置文件,处理文件不存在的异常,并确保流被正确关闭。

import java.io.*;
import java.util.Properties;
import java.util.logging.*;

public class ExceptionBestPractice {
    private static final Logger logger = Logger.getLogger("ExceptionDemo");
    
    // 1. 正确使用 try-with-resources 自动关闭
    public static String readFirstLine(String path) {
        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
            return br.readLine();
        } catch (IOException e) {
            // 记录日志,不要吞掉异常
            logger.log(Level.SEVERE, "读取文件失败: " + path, e);
            return null;  // 或抛出运行时异常
        }
    }
    
    // 2. 异常包装与链
    public static Properties loadConfig(String path) throws ConfigException {
        try (InputStream in = new FileInputStream(path)) {
            Properties props = new Properties();
            props.load(in);
            return props;
        } catch (IOException e) {
            // 包装为自定义异常,保留原始原因
            throw new ConfigException("加载配置失败: " + path, e);
        }
    }
    
    // 3. 运行时异常用于参数校验
    public static void setAge(int age) {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("年龄必须在0~150之间,实际: " + age);
        }
        // 正常处理
    }
    
    // 4. 不要空 catch
    public static void badPractice() {
        try {
            int a = 10 / 0;
        } catch (ArithmeticException e) {
            // 什么都不做,问题被隐藏了!这是最坏的实践
        }
    }
    
    public static void main(String[] args) {
        String line = readFirstLine("nonexist.txt");
        System.out.println("读取结果: " + line);
        
        try {
            Properties props = loadConfig("config.properties");
        } catch (ConfigException e) {
            e.printStackTrace();  // 正式环境用 logger
        }
        
        try {
            setAge(200);
        } catch (IllegalArgumentException e) {
            System.err.println(e.getMessage());
        }
    }
}

// 自定义检查型异常
class ConfigException extends Exception {
    public ConfigException(String message, Throwable cause) {
        super(message, cause);
    }
    public ConfigException(String message) {
        super(message);
    }
}

四、避坑要点

错误/误区后果正确做法
捕获异常后什么都不做(空 catch)掩盖问题,难以排查至少记录日志
在 finally 中关闭资源但不处理异常如果关闭失败,异常被吞没使用 try-with-resources
抛出检查型异常但调用者无法处理传递上层,导致处处 throws考虑包装为运行时异常
在循环中 catch 异常性能差,且可能陷入无限循环循环外处理,或使用重试策略
日志只打印 e.getMessage()丢失栈轨迹使用 log.error("msg", e) 打印完整堆栈

五、面试高频考点

Q1:什么时候应该捕获检查型异常,什么时候应该向上抛出?

如果当前层能恢复或做出合理响应(如重试、使用默认值),则捕获;否则向上抛出,让上层处理。对于框架代码,常包装为运行时异常抛出。

Q2:try-with-resources 的原理是什么?

实现了 AutoCloseable 的资源可以在 try 括号中声明,编译后生成 finally 块调用 close(),并处理异常抑制(addSuppressed)。

Q3:如何正确记录异常日志?

使用日志框架(如 java.util.logging、Log4j、SLF4J),记录完整堆栈:logger.error("操作失败", e); 不要只记录 e.getMessage()。

六、练习题

  1. 代码改错:指出下面代码的问题并改正。
    try {
        FileInputStream fis = new FileInputStream("test.txt");
        fis.read();
        fis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  2. 设计:写一个方法 divide(int a, int b),如果 b 为 0,抛出自定义运行时异常 DivideByZeroException。
  3. 场景:你正在开发一个网络请求库,当网络超时时应如何处理异常?

📊 你的学习进度

  • 当前:第35篇 / 共44篇 · 第五阶段:工具类、异常最佳实践、序列化(第32~35篇)
  • ✅ 已完成:第1~34篇
  • 📖 正在学:第35篇
  • ⏳ 待学习:第36~44篇

👉 📚 完整目录 & 学习指南 | 🔥 订阅本专栏,不错过每一篇

💡 本专栏每篇都包含:避坑表 + 面试高频考点 + 练习题。每天30分钟,100天拿offer!


👉 下一篇文章预告

《第36篇:选择最适合自己的NIO,一探流技术》

内容简介:BIO/NIO/AIO区别、流体系(字节/字符/缓冲/转换)、NIO核心组件(Channel/Buffer/Selector)、零拷贝。

💡 学完这篇,你将掌握Java I/O的全貌,并能根据场景选择合适的I/O模型。

📌 《Java 100 天进阶之路 | 从入门到上岗就业》 每天一篇,建议收藏 + 关注,一起100天拿offer!
👉 点击关注我,更新后第一时间收到推送!
📌 除了Java,我也在深挖智能物流实战(出版社WMS、托盘调度、机器学习落地)。如果你对技术在不同领域的实战感兴趣,欢迎点击我的头像,看看专栏《出版社物流WMS智能调度实战》。技术相通,思路可鉴。

Java多线程与异常处理详解 本文涵盖Java中学生考试成绩处理的异常机制,包括自定义RangeException和断言使用,并深入讲解多线程核心概念:线程状态、优先级、调度方式、Runnable接口应用及同步机制。通过实例演示sleep、join等方法的使用及其异常处理,帮助理解线程控制与协作。 阅读详情

相关推荐

STM32F103C8T6+TB6612驱动直流电机全攻略(附PWM调速代码)

本文提供了一份基于STM32F103C8T6微控制器和TB6612驱动模块的直流电机驱动完整解决方案。详细解析了硬件连接、STM32CubeMX配置、HAL库驱动代码编写,并附带了PWM调速代码实现。内容涵盖从基础原理到实战调试的全过程,旨在帮助开发者快速构建稳定、可精准调速的电机控制系统,适用于智能车、机器人等嵌入式项目。

weixin_29181861的博客 577

《2026全新 | Java 100 天进阶之路:从零基础到上岗就业,108篇完整学习地图》

摘要:不背八股文,不堆概念。44篇基础 + 64篇进阶(共108篇),100天助你达到Java就业水平,从容面对技术面试。 👉 零基础入门 / 校招社招突击 / 1-3年Java后端提升 / 想系统复盘全栈知识的开发者。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 9582

水下机器人仿真平台选型指南:从AirSim到Unity3D的深度对比

本文深入对比了AirSim+UE和Unity3D两大水下机器人仿真平台的核心架构、传感器仿真能力和水下环境建模特点。AirSim+UE凭借高精度物理仿真和丰富传感器支持成为专业研发首选,而Unity3D则以快速开发和灵活扩展见长。文章为研发团队提供了全面的选型指南,帮助优化水下实验的仿真效率与成本。

weixin_29009669的博客 445

《Java 100 天进阶之路》第44.1篇:Java常用工具类与异常处理速查表(2026版)

基础篇外挂第六弹!本文汇总 10 组工具类与异常处理实用速查:Objects 核心方法(null 安全三板斧:equals、hashCode、toString)、Collections 核心方法(排序/反转/不可变/同步包装)、Arrays 核心方法(排序/二分查找/拷贝/转 List)及其陷阱(Arrays.asList 固定大小、binarySearch 前需排序)、Collections.unmodifiableXxx 是视图陷阱、try-with-resources 标准模板、自定义异常规范、序列化

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 179

西门子PLC与汇川SV660P伺服速度模式配置实战指南

本文详细介绍了西门子S7-1200 PLC与汇川SV660P伺服驱动器在速度模式下的配置实战指南。从硬件接线、伺服参数配置到TIA Portal软件组态和PLC程序编写,提供了全面的操作步骤和实用技巧,帮助工程师快速解决伺服系统调试中的常见问题,确保系统稳定运行。

weixin_30316097的博客 491

解决倍福ADS通信错误1861和6:一次完整的TwinCAT3路由配置与故障排查实录

本文详细解析了在Linux系统上解决倍福ADS通信错误1861和6的完整流程,包括TwinCAT3路由配置与故障排查。通过实例演示了如何正确配置AMS NetID、使用adstool工具添加静态路由,以及高级网络抓包分析技巧,帮助工程师快速定位和解决通信问题。

weixin_30875157的博客 516

《Java 100 天进阶之路》第36篇:选择最适合自己的NIO,一探流技术

本文介绍了Java中的三种I/O模型:BIO(同步阻塞)、NIO(同步非阻塞)和AIO(异步非阻塞),重点分析了它们的适用场景和性能差异。文章详细讲解了传统流体系(字节流、字符流、缓冲流等)和NIO的核心组件(Channel、Buffer、Selector),并通过文件复制示例对比了BIO和NIO的实现方式。同时提供了NIO服务器的简化示例,总结了常见错误和面试考点,最后给出实践练习题。全文旨在帮助开发者理解不同I/O模型的特点,选择最适合应用场景的技术方案。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 555

第十六届蓝桥杯大赛软件赛(编程类)知识点大纲

难度:[1-3]难度:[1-5]难度:[1-3]难度:[2-5]难度:[1-5]

Future_yzx的博客 4103

《Java 100 天进阶之路》第34篇:Java序列化与反序列化详解

本文详细讲解了Java序列化与反序列化的核心概念和使用方法。主要内容包括:序列化将对象转为字节流便于存储传输,反序列化将字节流恢复为对象;通过实现Serializable接口使类可序列化;使用transient关键字跳过敏感字段序列化;serialVersionUID保证版本兼容性;提供了用户对象序列化的完整代码示例;指出了常见错误和安全隐患;解答了面试高频问题。文章强调要显式定义serialVersionUID,避免反序列化不可信数据,并提供了练习题巩固知识点。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 583

083、多帧降噪(MFR)与VST算法:低照度场景下的信噪比提升与鬼影抑制

本文深入探讨了多帧降噪(MFR)和VST算法在低照度场景中的应用与优化。作者从实际项目案例出发,指出单帧降噪的局限性,详细分析了MFR的核心原理与工程实现中的关键环节,包括帧对齐、帧选择、融合策略和鬼影抑制等技术要点。文章特别强调VST变换对噪声均匀化的重要性,并分享了实际开发中的调试经验与参数优化技巧,如"三明治"调试法和性能平衡策略。最后指出,优秀的MFR方案需要在信噪比提升、鬼影抑制和纹理保留之间找到场景化的平衡点,建议开发者通过真实场景测试验证算法效果。全文既有理论分析,又包含丰富的实战经验和技术细

zzfmlxs的博客 116

YOLO11改进 | 注意力机制 | 添加SimAM注意力机制【全网独家+附完整代码】

yolo11,yolo11改进,yolo11创新,yolo11添加注意力机制

kay_545 1219

【Java】异常处理指南

📃1. 异常是什么。

island1314的博客 3999

YOLO26涨点改进 | 细节涨点篇 | 源自SCI一区 | YOLO26引入HWD小波下采样模块,而不会显著增加计算开销,(适合小目标分割任务、小目标检测任务)

本文提出了一种基于Haar小波变换的下采样模块HWD,用于改进YOLO26目标检测性能。HWD模块通过小波变换降低特征图分辨率,同时将空间信息编码到通道维度,有效保留了关键信息。相比传统下采样方法,HWD能显著减少信息不确定性,提升小目标检测精度。实验表明,该模块可无缝集成到CNN架构中,不增加计算开销。文章详细介绍了HWD的实现原理、代码结构以及在YOLO26中的集成方法,并提供了两种改进版yaml配置文件。该创新模块已在多种数据集上验证有效,特别适合语义分割和目标检测任务。

Ai缝合怪、助力小伙伴高效发论文 387

Java基础之(0-100)

每日十个面试题--(java基础篇)-(1-10) 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什 么限制? 2、Java有没有goto? 3、说说&和&&的区别。 4、在JAVA中如何跳出当前的多重嵌套循环? 5、switch语句能否作用在byte上,能否作用在long上,能否作用在 String上? 6、short s1= 1; s1 =(s1+1是int类型,而等号左边的是short类型,所以需要强转)1 + 1;有什么错? short s1 = 1;

lyh1023812的博客 397

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Java异常处理(详细)

什么是异常?异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域的情况,称之为异常。java中异常的体系是怎么样的呢?.Java中的所有不正常类都继承于Throwable类。Throwable主要包括两个大类,一个是Error类,另一个是Exception类;其中Error类中包括虚拟机错误和线程死锁,一旦Error出现了,程序就彻底的挂了,被称为程序终结者.Exception类,也就是通常所说的“异常”。

mr_yuanshen的博客 1379

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java入门必背100条

Java必背100条 1、编写:编写的Java代码保存在以“.java”结尾的源文件中。 2、编译:使用javac.exe命令编译java源文件,生成字节码文件。格式:javac 源文件名.java 3、运行:使用java.exe命令解释运行字节码文件。格式:java 类名 4、在一个java源文件中可以声明多个class,但是只能最多有一个类声明为public,而且被声明为public的类的...

野生的程序员 1万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

100天Java全栈工程师实战训练营 - 课程大纲

📝【100天Java全栈学习计划】本课程采用"核心知识+项目实战"模式,分5个阶段系统培养Java全栈开发能力: 1️⃣ 基础阶段(25天) 掌握JavaSE核心语法、OOP思想及控制台应用开发,完成学生成绩管理系统项目。 2️⃣ 数据与前端(20天) 学习MySQL数据库、MyBatis框架和Vue3前端开发,实现个人博客系统。 3️⃣ SpringBoot开发(15天) 深入SpringBoot生态,整合Redis等中间件,升级博客系统功能。 4️⃣ 微服务实战(25天) 基于Sp

weixin_38291577的博客 750

java面试100刷

50 请解释Java中的日期和时间API,包括Date、Calendar、SimpleDateFormat、LocalDateTime等类的使用方法和优缺点。54 请解释Java中的Web开发,包括Servlet、JSP、JSF、Struts、Spring MVC等框架的使用方法和优缺点。52 请解释Java中的XML和JSON,包括DOM、SAX、JAXB、Jackson等技术的使用方法和优缺点。36 请列举Java中的开发工具,包括IDE、构建工具、版本控制工具等,并解释它们的使用方法和优缺点。

m0_51250461的博客 143

【Java语言设计】——期末复习(冲刺篇)

📖 前言:快考试了,做篇期末总结,都是重点与必考点。题型:判断题、单选题、程序综合题(阅读程序并填空)、改错题、代码评价题、英语专业阅读题(如给出某函数的开发文档(英文)用法解释要求翻译为中文)、编程设计题(继承、接口、多态)

HinsCoder的博客 2823

一文读懂Java基础/进阶/异常/容器/底层知识文集

在上述代码中,我们使用Random类来生成随机数。通过调用nextInt方法,传入参数max - min + 1,再加上min,即可生成10到100之间的随机数。1. 静态初始化:在定义数组的同时,为数组元素赋初值。语法:数据类型[] 数组名 = {元素1, 元素2, …};示例:int[] numbers = {1, 2, 3, 4, 5}

m0_50308467的博客 1372

java 100 基础题_JAVA基础面试100题(一)新手必看

JAVA基础面试100题(一)新手必看-1.jpg (30.43 KB, 下载次数: 0)2018-7-10 19:27 上传更多精彩内容关注“柠檬学园”1、String和StringBuffer有什么区别?int 和 Integer有什么不合, float f=3.4是否正确2、异常(Exception)分几种类型?有什么区别?写出几个常见异常(若记不得异常的英文名,写中文名亦可)3、写出几种常...

weixin_39625782的博客 587

18.<异常处理>

本篇博客主要讲解Java基础语法中的 一、异常的基础知识 异常的概念、异常的体系结构、异常的分类 二、异常的处理 防御式编程、异常处理主要的5个关键字:、异常的抛出、异常的捕获(重点)、异常声明throws 、快捷键(alt + Insert)、try-catch捕获并处理、finally关键字 【面试题】: 1. throw 和 throws 的区别、2. finally中的语句一定会执行吗? 异常的处理流程、自定义异常类

m0_73456341的博客 1787

Java面试题读这一篇就够了:100个互联网大厂Java面试真题整理面试必考点【值得收藏】

据官方数据统计,在全球编程语言工程师的数量上,JavaEE 以900 万的程序员数量位居首位,很多软件的开发都离不开它。这里整理了100 家IT 名(阿里、百度、腾讯、携程)企面试题,为了帮助更多爱好并想学习编程的同学,整理了这篇资源帖子,只为帮助更多的人受益。内容包含:常见Java问题、Java线程、Java集合类、垃圾回收器(Garbage Collectiors)、异常处理、Java小应用程序(Applet)、Swing、JDBC、远程方法调用(RMI)、Servlet、JSP等内容。........

Jerry学长 1281

44篇通关!Java基础篇终极总结:一张图、三张表,把全部知识点装进脑子(2026版)

Java基础篇44篇终极总结!一张学习路线图 + 三张速查表 + 面试题 + 避坑清单,帮你把零散知识串成体系。附PDF福利,进阶篇预告。收藏本文,面试前复习效率翻倍。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 703

2020年Java面试100题

一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境。 具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还...

liinux-Talk is cheap,show me the code. 1448
上一篇: 《Java 100 天进阶之路》第34篇:Java序列化与反序列化详解
下一篇: Java 23 种设计模式:从踩坑到精通 —— 开篇及系列介绍
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值