前言:关于“心态崩了”的瞬间

坐标:图书馆深夜档(由于没抢到插座,电脑电量仅剩 15%)

状态:刚敲完 500 行代码,一运行结果弹出一页红字。

碎碎念: 兄弟们,今天我差点当场去世。 本来以为逻辑写得无懈可击,结果一点运行,控制台直接炸出一片红。那一瞬间,我觉得那些红字不是代码,而是对我智商的“血泪控诉”。

学长路过看了一眼,淡定地说:“淡定,这叫异常。你要是哪天运行完控制台干干净净,那才叫见鬼了。关键是你得看懂谁是 Error,谁是 Exception。”

回来后我把 Java 的异常家谱翻了个底朝天。今天咱就来聊聊这些“爆红”背后的真相,看看怎么优雅地处理这些不速之客!

🚀 目录

  1. 异常家族:Throwable 的祖宗十八代

  2. Error vs Exception:绝症与感冒的区别

  3. 异常双煞:运行时异常与编译时异常

  4. 抛接艺术:throw, throws 与 try-catch

  5. 自定义异常:给你的 Bug 起个好名字

  6. 大厂面试:关于异常的那些“深坑”

  7. 结语:优秀的程序员是修出来的

1. 异常家族:Throwable 的祖宗十八代

在 Java 里,所有的“不正常情况”都有一个共同的祖宗:java.lang.Throwable

1.1 两个大儿子

Throwable 膝下有两个儿子,性格完全不同:

  • Error:这种是“顶级灾难”。比如 OutOfMemoryError(内存溢出),这就像是房子塌了,你作为程序员,除了对着屏幕发呆或者重启电脑,基本上无能为力。

  • Exception:这种是“程序 Bug”。比如 NullPointerException(空指针),这就像是感冒发烧。虽然难受,但能治,而且必须治。

2. Error vs Exception:绝症与感冒的区别

特征

Error (错误)

Exception (异常)

严重程度

致命伤,JVM 基本瘫痪

非致命伤,程序可挽救

能否处理

无法处理,只能认栽

必须处理(捕获或抛出)

典型案例

栈溢出、内存不足

空指针、数组越界、文件找不到

3. 异常双煞:运行时异常与编译时异常

Exception 门下,又分成了两派。这是大学生最容易搞混的地方:

3.1 运行时异常 (RuntimeException)

这一派叫 “非受检异常 (Unchecked Exception)”

  • 特点:编译器不强迫你处理。

  • 场景:你写代码不细心。比如 1/0a[10](只有 5 个元素)。

  • 大学生比喻:就像你出门不带伞。虽然天气预报没强制,但下雨了你就得淋着。

3.2 编译时异常 (Checked Exception)

这一派叫 “受检异常 (Checked Exception)”

  • 特点:编译器盯着你,不处理就不给过。

  • 场景:外部环境不可控。比如读文件(万一文件被室友删了呢?)、连数据库(万一断网了呢?)。

  • 大学生比喻:就像你进实验室必须穿白大褂。规定死死的,不穿不让进。

4. 抛接艺术:throw, throws 与 try-catch

处理异常就像打棒球:

4.1 throws(甩锅)

写在方法声明上。告诉调用者:“我这儿可能有炸弹,你要调我,你得做好防御准备。”

public void readFile() throws FileNotFoundException {
    // 逻辑
}

4.2 throw(扔炸弹)

写在方法体里。主动制造一个异常:“这儿数据不对,我不干了,炸给你看!”

4.3 try-catch-finally(接球)

这是最稳妥的办法:

  • try:尝试跑代码。

  • catch:出事了怎么办?(比如打印一句话安抚用户)。

  • finally:不管出不出事,都得干的事(比如关掉文件流)。

5. 自定义异常:给你的 Bug 起个好名字

有时候 Java 自带的异常不够表达我们的愤怒。 比如你想写一个“外卖还没到”的异常:

public class TakeoutLateException extends Exception {
    public TakeoutLateException(String message) {
        super(message);
    }
}

6. 大厂面试:关于异常的那些“深坑”

Q1:final, finally, finalize 有啥区别?

(这题我们在日记 04 详细聊过,这就是考记忆力了!)

Q2:如果在 finally 块里有 return 语句,会发生什么?

答案:它会覆盖掉 try 块里的 return。这是一个非常坏的习惯,千万别在 finally 里写 return!

Q3:继承关系中,子类重写方法抛出的异常有限制吗?

答案:有!子类重写方法抛出的异常,不能超出父类原本抛出的异常范围。

  • 比喻:老爸说“我可能会感冒”,你不能说“我可能会得绝症”。

7. 结语

写完这篇日记,电脑电量只剩 2% 了,我也该撤了。 异常并不可怕,它是程序在向你“求救”。一个成熟的 Java 程序员,不仅要会写功能,更要学会如何体面地处理这些“意外”。

作为大学生的我们:

  • 代码要写得健壮

  • 心态要保持平稳

如果你也曾被满屏红字搞到心跳加速,点个赞安慰一下!下期聊聊throw和throws

更多推荐