Java 运行时异常和编译时异常之间的区别是什么? 📅 发布时间:2026/7/14 16:02:12 👁️ 浏览次数: Java 中的异常分为两大类运行时异常和编译时异常也称为检查型异常。它们在处理方式、继承层次和使用场景上有重要区别。异常层次结构Throwable ├── Error错误不处理 └── Exception异常 ├── RuntimeException运行时异常非检查型 │ ├── NullPointerException │ ├── ArrayIndexOutOfBoundsException │ ├── ArithmeticException │ ├── ClassCastException │ └── ... └── 其他异常编译时异常检查型 ├── IOException ├── SQLException ├── FileNotFoundException └── ...主要区别对比特性运行时异常编译时异常继承类RuntimeExceptionException非RuntimeException检查时机运行时编译时必须处理不强制必须处理声明要求不需要声明必须声明或捕获常见例子NullPointerException, ArrayIndexOutOfBoundsExceptionIOException, SQLException处理方式可选强制运行时异常特点继承自RuntimeException编译器不强制要求处理通常表示编程错误可以在代码中避免常见运行时异常// 1. NullPointerException - 空指针异常Stringstrnull;intlengthstr.length();// NullPointerException// 2. ArrayIndexOutOfBoundsException - 数组越界int[]arrnewint[5];intvaluearr[10];// ArrayIndexOutOfBoundsException// 3. ArithmeticException - 算术异常intresult10/0;// ArithmeticException// 4. ClassCastException - 类型转换异常ObjectobjHello;Integernum(Integer)obj;// ClassCastException// 5. IllegalArgumentException - 非法参数异常publicvoidsetAge(intage){if(age0||age150){thrownewIllegalArgumentException(年龄必须在0-150之间);}}// 6. NumberFormatException - 数字格式异常intnumInteger.parseInt(abc);// NumberFormatException// 7. IndexOutOfBoundsException - 索引越界ListStringlistnewArrayList();Stringitemlist.get(0);// IndexOutOfBoundsException运行时异常处理示例publicclassRuntimeExceptionExample{// 不需要声明运行时异常publicintdivide(inta,intb){returna/b;// 可能抛出 ArithmeticException}// 可选处理运行时异常publicvoidprocessString(Stringstr){// 方式1不处理让调用者处理intlengthstr.length();// 方式2主动检查避免异常if(str!null){intlength2str.length();}// 方式3捕获处理try{intlength3str.length();}catch(NullPointerExceptione){System.out.println(字符串为空);}}// 抛出自定义运行时异常publicvoidsetAge(intage){if(age0||age150){thrownewIllegalArgumentException(年龄必须在0-150之间);}}}编译时异常特点继承自Exception但不是RuntimeException编译器强制要求处理通常表示外部环境问题必须声明或捕获常见编译时异常// 1. IOException - 输入输出异常importjava.io.*;publicvoidreadFile(Stringfilename)throwsIOException{FileReaderreadernewFileReader(filename);// 必须声明 throws IOException}// 2. FileNotFoundException - 文件未找到异常publicvoidopenFile(Stringpath)throwsFileNotFoundException{FileInputStreamfisnewFileInputStream(path);// 必须声明 throws FileNotFoundException}// 3. SQLException - 数据库异常importjava.sql.*;publicvoidqueryData()throwsSQLException{ConnectionconnDriverManager.getConnection(jdbc:mysql://localhost/test);Statementstmtconn.createStatement();ResultSetrsstmt.executeQuery(SELECT * FROM users);// 必须声明 throws SQLException}// 4. ClassNotFoundException - 类未找到异常publicvoidloadClass(StringclassName)throwsClassNotFoundException{Class.forName(className);// 必须声明 throws ClassNotFoundException}// 5. InterruptedException - 中断异常publicvoidsleep()throwsInterruptedException{Thread.sleep(1000);// 必须声明 throws InterruptedException}// 6. ParseException - 解析异常importjava.text.*;publicvoidparseDate(StringdateStr)throwsParseException{SimpleDateFormatsdfnewSimpleDateFormat(yyyy-MM-dd);Datedatesdf.parse(dateStr);// 必须声明 throws ParseException}编译时异常处理示例importjava.io.*;importjava.sql.*;publicclassCheckedExceptionExample{// 方式1声明异常让调用者处理publicvoidreadFile(Stringfilename)throwsIOException{FileReaderreadernewFileReader(filename);BufferedReaderbrnewBufferedReader(reader);Stringlinebr.readLine();System.out.println(line);br.close();}// 方式2捕获异常publicvoidreadFileSafe(Stringfilename){try{FileReaderreadernewFileReader(filename);BufferedReaderbrnewBufferedReader(reader);Stringlinebr.readLine();System.out.println(line);br.close();}catch(IOExceptione){System.out.println(读取文件失败: e.getMessage());}}// 方式3捕获后重新抛出publicvoidreadFileAndRethrow(Stringfilename)throwsCustomException{try{FileReaderreadernewFileReader(filename);BufferedReaderbrnewBufferedReader(reader);Stringlinebr.readLine();System.out.println(line);br.close();}catch(IOExceptione){thrownewCustomException(文件处理失败,e);}}// 方式4使用 try-with-resources推荐publicvoidreadFileWithResources(Stringfilename){try(FileReaderreadernewFileReader(filename);BufferedReaderbrnewBufferedReader(reader)){Stringlinebr.readLine();System.out.println(line);}catch(IOExceptione){System.out.println(读取文件失败: e.getMessage());}}// 多个异常的处理publicvoidprocessFile(Stringfilename)throwsIOException,ClassNotFoundException{// 可以声明多个异常FileReaderreadernewFileReader(filename);Class.forName(com.example.SomeClass);}// 多个异常的捕获publicvoidhandleMultipleExceptions(Stringfilename){try{FileReaderreadernewFileReader(filename);Class.forName(com.example.SomeClass);}catch(IOException|ClassNotFoundExceptione){// Java 7 可以捕获多个异常System.out.println(处理异常: e.getMessage());}}}实际应用场景对比1.文件操作编译时异常importjava.io.*;publicclassFileProcessor{// 编译时异常 - 必须处理publicvoidprocessFile(StringinputPath,StringoutputPath)throwsIOException{try(BufferedReaderreadernewBufferedReader(newFileReader(inputPath));BufferedWriterwriternewBufferedWriter(newFileWriter(outputPath))){Stringline;while((linereader.readLine())!null){// 处理每一行StringprocessedprocessLine(line);writer.write(processed);writer.newLine();}}// IOException 是编译时异常必须处理}privateStringprocessLine(Stringline){// 这里可能抛出运行时异常if(linenull){thrownewIllegalArgumentException(行不能为空);}returnline.toUpperCase();}}2.数据库操作编译时异常importjava.sql.*;publicclassDatabaseManager{publicUsergetUserById(intuserId)throwsSQLException{Connectionconnnull;PreparedStatementstmtnull;ResultSetrsnull;try{connDriverManager.getConnection(jdbc:mysql://localhost/mydb);StringsqlSELECT * FROM users WHERE id ?;stmtconn.prepareStatement(sql);stmt.setInt(1,userId);rsstmt.executeQuery();if(rs.next()){returnnewUser(rs.getInt(id),rs.getString(name));}returnnull;}finally{// 清理资源if(rs!null)rs.close();if(stmt!null)stmt.close();if(conn!null)conn.close();}// SQLException 是编译时异常必须处理}}3.业务逻辑运行时异常publicclassUserService{// 运行时异常 - 不需要声明publicvoidregisterUser(Stringusername,Stringpassword){// 参数验证 - 抛出运行时异常if(usernamenull||username.trim().isEmpty()){thrownewIllegalArgumentException(用户名不能为空);}if(passwordnull||password.length()6){thrownewIllegalArgumentException(密码长度不能少于6位);}// 检查用户名是否已存在if(userExists(username)){thrownewIllegalStateException(用户名已存在);}// 保存用户saveUser(username,password);}// 运行时异常 - 不需要声明publicUsergetUser(intuserId){UseruseruserRepository.findById(userId);if(usernull){thrownewUserNotFoundException(用户不存在: userId);}returnuser;}// 自定义运行时异常publicstaticclassUserNotFoundExceptionextendsRuntimeException{publicUserNotFoundException(Stringmessage){super(message);}}}异常处理最佳实践1.何时使用运行时异常// ✅ 适合使用运行时异常的情况publicclassBankAccount{privatedoublebalance;publicvoidwithdraw(doubleamount){// 编程错误 - 应该在调用前检查if(amount0){thrownewIllegalArgumentException(取款金额不能为负数);}// 业务规则违反 - 运行时异常if(amountbalance){thrownewIllegalStateException(余额不足);}balance-amount;}publicvoiddeposit(doubleamount){// 参数验证if(amount0){thrownewIllegalArgumentException(存款金额必须大于0);}balanceamount;}}2.何时使用编译时异常// ✅ 适合使用编译时异常的情况publicclassFileDownloader{publicvoiddownloadFile(Stringurl,StringsavePath)throwsIOException{// 文件操作 - 外部环境问题使用编译时异常URLwebsitenewURL(url);ReadableByteChannelrbcChannels.newChannel(website.openStream());FileOutputStreamfosnewFileOutputStream(savePath);fos.getChannel().transferFrom(rbc,0,Long.MAX_VALUE);}publicvoidprocessDownloadedFile(StringfilePath)throwsIOException,ParseException{// 多个可能的编译时异常BufferedReaderreadernewBufferedReader(newFileReader(filePath));Stringcontentreader.readLine();// 解析日期SimpleDateFormatsdfnewSimpleDateFormat(yyyy-MM-dd);Datedatesdf.parse(content);}}3.异常处理策略publicclassExceptionHandlingStrategy{// 策略1恢复并继续publicvoidprocessMultipleFiles(ListStringfilePaths){for(StringfilePath:filePaths){try{processFile(filePath);}catch(IOExceptione){// 记录错误但继续处理其他文件System.err.println(处理文件失败: filePath, 错误: e.getMessage());}}}// 策略2转换异常类型publicUserloadUser(intuserId)throwsUserLoadException{try{returnuserRepository.findById(userId);}catch(SQLExceptione){// 将底层异常转换为业务异常thrownewUserLoadException(加载用户失败,e);}}// 策略3提供默认值publicStringgetConfigValue(Stringkey){try{returnconfigLoader.load(key);}catch(IOExceptione){// 返回默认值而不是抛出异常returndefault;}}// 自定义业务异常publicstaticclassUserLoadExceptionextendsException{publicUserLoadException(Stringmessage,Throwablecause){super(message,cause);}}}异常处理注意事项✅ 推荐做法// 1. 具体异常处理try{// 代码}catch(FileNotFoundExceptione){// 处理文件未找到}catch(IOExceptione){// 处理其他IO异常}// 2. 提供有意义的错误信息thrownewIllegalArgumentException(年龄必须在0-150之间当前值: age);// 3. 保留原始异常信息try{// 代码}catch(IOExceptione){thrownewBusinessException(处理失败,e);}// 4. 清理资源try(FileReaderreadernewFileReader(file.txt)){// 使用资源}catch(IOExceptione){// 处理异常}❌ 避免的做法// 1. 捕获所有异常try{// 代码}catch(Exceptione){// 太宽泛难以处理}// 2. 吞掉异常try{// 代码}catch(IOExceptione){// 什么都不做}// 3. 捕获后立即抛出try{// 代码}catch(IOExceptione){throwe;// 没有意义}// 4. 不恰当的使用运行时异常publicvoidreadFile(Stringpath){// 文件操作应该使用编译时异常thrownewRuntimeException(文件读取失败);}总结运行时异常用途表示编程错误和逻辑错误处理可选通常通过代码检查避免例子NullPointerException, IllegalArgumentException原则快速失败暴露问题编译时异常用途表示外部环境问题和可恢复错误处理必须处理强制调用者关注例子IOException, SQLException原则优雅处理提供恢复机制理解这两种异常的区别有助于编写更健壮、更易维护的 Java 代码。运行时异常用于快速发现编程错误编译时异常用于处理外部环境的不确定性。
图论——最短路Dijkstra算法 Dijkstra算法:给定一个源点,求解从源点到每个点的最短路径长度。单源最短路径算法。 适用范围:有向图、边的权值没有负数普通堆实现的Dijkstra算法最普遍、最常用:a.节点弹出过就忽略 b.节点没弹出过,让其它没弹出节点… 2026/7/11 12:48:38
【GLM-5 陪练式前端新手入门】第四篇:卡片布局 —— 让个人主页内容更有层次 【GLM-5 陪练式前端新手入门】第四篇:卡片布局 —— 让个人主页内容更有层次 目录 【GLM-5 陪练式前端新手入门】第四篇:卡片布局 —— 让个人主页内容更有层次 1 项目背景:给个人主页填充 “内容卡片” 2 AI 赋能:向 GLM-5 提… 2026/7/13 11:40:17
【GLM-5 陪练式前端新手入门】第三篇:网页导航栏 —— 搭建个人主页的 “指路牌” 【GLM-5 陪练式前端新手入门】第三篇:网页导航栏 —— 搭建个人主页的 “指路牌” 目录 【GLM-5 陪练式前端新手入门】第三篇:网页导航栏 —— 搭建个人主页的 “指路牌” 1 项目背景:给个人主页加上 “指路牌” 2 AI 赋能:向… 2026/7/13 21:47:19
ADS58J63 JESD204B接口配置与调试实战指南 1. 项目概述与核心价值 在宽带接收机、相控阵雷达或者多通道软件无线电这类对数据吞吐量和信号纯净度要求极高的系统中,高速模数转换器(ADC)与现场可编程门阵列(FPGA)之间的数据传输一直是个设计难点。传统的并行LVDS接… 2026/7/15 8:46:35
RetroWrite x64与ARM64版本对比:功能差异与架构支持详解 RetroWrite x64与ARM64版本对比:功能差异与架构支持详解 【免费下载链接】retrowrite RetroWrite -- Retrofitting compiler passes through binary rewriting 项目地址: https://gitcode.com/gh_mirrors/re/retrowrite RetroWrite是一款强大的静态二进制重写… 2026/7/15 8:44:34
影刀RPA 异常登录检测:多源IP比对与安全告警 影刀RPA 异常登录检测:多源IP比对与安全告警 作者:林焱 什么情况用什么 安全团队最怕的事:员工账号被盗了,但两天后才从审计日志里发现。如果能做到"异地IP登录→30秒内告警",损失可以减到最小。 影刀RPA… 2026/7/15 8:44:34
TradingView Webhooks Bot未来展望:路线图与功能规划解析 TradingView Webhooks Bot未来展望:路线图与功能规划解析 【免费下载链接】tradingview-webhooks-bot a framework 🏗 for trading with tradingview webhooks! 项目地址: https://gitcode.com/gh_mirrors/tr/tradingview-webhooks-bot TradingVi… 2026/7/15 8:44:34
模板驱动文档自动化:从填空到智能生成的工程实践 1. 项目概述:用模板把文档生产变成“填空题” 你有没有过这种体验:每周要交三份客户方案,每份结构雷同——封面、目录、痛点分析、解决方案、报价页、服务承诺——但每次都要从零新建Word、手动调格式、复制粘贴旧内容、反复检查页眉页脚是否… 2026/7/15 8:42:33
副热带高压如何影响台风路径:以台风巴威为例的气象原理与教学应用 最近在备课高中地理课程时,发现很多学生对副热带高压(副高)与台风路径的关系理解不够深入。特别是像台风"巴威"这样的典型案例,其移动路径受到副高系统的显著影响。本文将围绕副高如何影响台风巴威移动路径这一主题&… 2026/7/15 8:42:33
行星减速机的工作原理是什么?从齿轮运动关系到减速比计算 一、行星齿轮机构的组成 标准行星齿轮机构主要包括: 太阳轮; 行星轮; 内齿圈; 行星架。 太阳轮位于机构中心。 多个行星轮围绕太阳轮均匀布置,行星轮内侧与太阳轮外啮合,外侧与内齿圈内啮合。 行星轮通过轴… 2026/7/15 0:03:00
阅读Java开源框架源码的心得分享! 前几日闲来无事有幸看到了一位博主分享自己阅读开源框架源码的心得,看了之后也引发了我的一些深度思考。我们为什么要看源码?我们该怎么样去看源码? 其中前者那位博主描述的我觉得很全了(如下图所示),就不做… 2026/7/15 0:03:00
【LINUX】驱动 【LINUX驱动】【字符设备】【中断】【Platform】【网课 设备树】【GPIO】【PINCTRL】【INPUT】【IIC】【SPI】【网络驱动】【屏幕驱动】【一 设备树】【二 内核模块编译】【三 基本驱动框架】【四 Platform总线设备驱动框架】【五 驱动子系统】【六 综合】 2026/7/15 0:07:01
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/13 8:31:55
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/14 18:25:04
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/14 5:09:41