很多人分不清!Java 运行时异常和编译时异常的真正区别

原文来自于:zha-ge.cn/java/18

很多人分不清!Java 运行时异常和编译时异常的真正区别

深夜的一次"翻车"

那是一个月黑风高的夜晚(好吧,其实就是普通的周五加班),我正在为公司的订单系统写一个文件上传功能。代码写得飞起,心情美滋滋,准备提交代码回家吃宵夜。

然而,当我满怀信心地点击运行按钮时...

java 复制代码
Exception in thread "main" java.io.FileNotFoundException: upload/orders.txt (系统找不到指定的路径。)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at OrderUploader.processFile(OrderUploader.java:23)

什么?!我明明写的代码在IDE里没有任何红色波浪线啊!为什么运行时突然冒出个异常?

这就是我第一次真正意识到 编译时异常运行时异常 区别的时刻。

两兄弟的身世之谜

Java的异常家族就像两兄弟:

异常类型 别名 检查时机 是否强制处理
编译时异常 Checked Exception 编译期 必须处理
运行时异常 Unchecked Exception 运行期 可选处理

编译时异常就像那个严格的哥哥,在你写代码时就会跳出来说:"兄弟,这里可能出问题,你必须想好怎么处理!"

运行时异常则像调皮的弟弟,编译时乖乖的,运行时突然给你来个"惊喜"。

踩坑瞬间:文件操作的"温柔陷阱"

回到我那个翻车的夜晚。我写的代码是这样的:

java 复制代码
public void uploadOrderFile(String fileName) throws IOException {
    FileInputStream fis = new FileInputStream(fileName);
    // 处理文件内容...
    fis.close();
}

IDE为什么没有报错?因为我已经在方法签名上声明了throws IOException!这是编译时异常的经典处理方式。

但问题来了:当我在调用这个方法的地方忘记处理异常时...

java 复制代码
// 这样写IDE会报红!必须处理IOException
orderUploader.uploadOrderFile("orders.txt"); 

这时候IDE才会提醒你:老兄,你调用的方法可能抛出编译时异常,必须处理!

转折:运行时异常的"隐身术"

相比之下,运行时异常就"狡猾"多了。比如最常见的空指针异常:

java 复制代码
List<String> orderList = getOrderList(); // 可能返回null
// 下面这行编译完全正常,但运行时可能爆炸
orderList.add("新订单"); // NullPointerException等着你呢

IDE不会给你任何警告,代码编译得好好的,结果运行时突然:

arduino 复制代码
Exception in thread "main" java.lang.NullPointerException

这就是运行时异常的特点:编译器不管,全靠程序员自觉!

经验启示:如何优雅应对两兄弟

经过无数次踩坑后,我总结出了这样的经验:

编译时异常的处理策略

  • 文件IO、网络连接、数据库操作 → 大概率是编译时异常
  • 必须用 try-catch 或者 throws 声明
  • 适合处理"预料之中"的异常情况

运行时异常的防范策略

  • 空指针、数组越界、类型转换 → 典型的运行时异常
  • 通过代码逻辑预防(null检查、边界校验)
  • 适合处理"编程错误"

最佳实践

  1. 编译时异常:该处理就处理,别一味往上抛
  2. 运行时异常:提前预防胜过事后处理
  3. 自定义异常:根据业务需求选择继承RuntimeException还是Exception

醒悟时刻

现在回想起那个加班的夜晚,我才明白:

  • 编译时异常像个严格的老师,强制你思考异常处理
  • 运行时异常像个隐藏的地雷,全靠经验和习惯来规避

掌握了这两者的区别,写代码时就能做到:该严格时严格,该灵活时灵活。毕竟,异常处理不是为了应付编译器,而是为了让程序更健壮,让自己少加班!

现在的我,再也不会在深夜被突如其来的异常吓到了。因为我知道,每一个异常都有它的"脾气",掌握了它们的性格,就能和它们和谐相处。

你呢?还在被这两兄弟搞得晕头转向吗?

相关推荐
Slow菜鸟1 小时前
SpringBoot集成Elasticsearch | Elasticsearch 8.x专属Java Client
java·spring boot·elasticsearch
Miraitowa_cheems1 小时前
LeetCode算法日记 - Day 82: 环形子数组的最大和
java·数据结构·算法·leetcode·决策树·线性回归·深度优先
豐儀麟阁贵2 小时前
4.5数组排序算法
java·开发语言·数据结构·算法·排序算法
Halo_tjn3 小时前
Java Map集合
java·开发语言·计算机
程序猿小蒜4 小时前
基于springboot的车辆管理系统设计与实现
java·数据库·spring boot·后端·spring·oracle
zl9798994 小时前
SpringBoot-Web开发之Web原生组件注入
java·spring boot·spring
小羊学伽瓦4 小时前
【Java数据结构】——常见力扣题综合
java·数据结构·leetcode·1024程序员节
I'm Jie5 小时前
(五)Gradle 依赖传递与冲突处理
java·spring boot·spring·kotlin·gradle·maven
我命由我123455 小时前
Spring Cloud - Spring Cloud 声明式接口调用(Fiegn 声明式接口调用概述、Fiegn 使用)
java·后端·spring·spring cloud·微服务·架构·java-ee
_extraordinary_5 小时前
Java Spring事务,事务的传播机制
java·开发语言·spring