iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
JavaScript

大學以前只看過那隻貓?用白話文帶你從 Python 跨進 JavaScript系列 第 14 篇

【Day 14】天災還是人禍?搞懂編譯器差別待遇的真相:Checked 與 Unchecked 派系對決

  • 分享至 

  • xImage
  •  

寫 Java 到現在,你一定遇過這種差別待遇:
寫檔案讀取 new FileReader("test.txt") 時,明明程式碼還沒按執行,IDE 就整行畫紅線警告:「你必須寫 try-catch 或在方法門口寫 throws,否則不准編譯!」
可是寫陣列超過長度 arr[999] 或是除以零 10 / 0 時,編譯器卻安安靜靜、一句話也不說,直到按下 Run 程式才當場暴斃噴紅字。
為什麼編譯器對有些錯誤管很寬,對有些錯誤卻睜一隻眼閉一隻眼?
這就是 Java 例外世界裡壁壘分明的兩大陣營:檢查型例外(Checked Exception) 與 非檢查型例外(Unchecked Exception)!
翻開家族族譜:正妻生的小錯就管,阿貓阿狗生的闖禍直接家規處置!
要搞懂它們的脾氣,看一眼 Java 的 Throwable 族譜就真相大白:
Throwable(老祖宗)
/
Error Exception(例外家族)
(硬體/系統崩潰) /
/
Checked Exception RuntimeException
(檢查型:編譯期拿刀盯著你) (非檢查型:平時放養,執行期暴斃)
例如: IOException 例如: NullPointerException
SQLException ArrayIndexOutOfBoundsException
FileNotFoundException ArithmeticException
Checked Exception(正妻生的,從小盯到大):
只要直接繼承 Exception通通屬於此類。
編譯器把它當作掌上明珠,嚴厲到極點,只要程式碼有一絲絲可能出事(例如檔案找不到、網路斷線),編譯器在寫 code 當下就直接拿戒尺敲桌子:「現在、立刻、馬上把 try-catch 或 throws 補上,不然休想編譯!」
Unchecked Exception(繼承 RuntimeException,放養型逆子):
只要繼承自 RuntimeException(包括它的子子孫孫),通通屬於非檢查型。
編譯器平時對它睜一隻眼閉一隻眼,寫錯了也完全不嗶嗶。但千萬別高興得太早——這種放養代價極高,一旦按下 Run 真的踩雷(例如指標指到 null、陣列爆掉)直接二十大板打下來,程式當場當機暴斃!
一句話總結兩者的本質區別:
Checked(環境風險): 就算工程師 code 寫得再完美,硬碟壞掉、拔掉網路線還是會爆,所以編譯器強制你事先準備好逃生計畫。
Unchecked(低級失誤): 陣列越界、除以零、取到 null,這純粹是工程師邏輯沒防呆,自己回去把 code 改好,編譯器懶得替你的粗心擦屁股!

為什麼編譯器要這樣差別待遇?
:「編譯器幹嘛那麼囉唆?既然會出事,為什麼不全部幫我檢查?或者乾脆全部放行讓我自己跑跑看?」
面對 Checked Exception(外部天災):防患於未然
就算你是世界上最頂尖的工程師,程式碼寫得滴水不漏,只要使用者手賤把要讀的檔案刪除、或是伺服器網路線被清潔阿姨不小心踢掉,系統就會當掉。
這不是你的演算法寫錯,而是現實世界的不可抗力。
Java 拿刀逼你,就是為了防範那些不看使用說明的操作與突發狀況:在寫程式的當下,就必須預先替使用者鋪好逃生通道(try-catch 或 throws)!
面對 Unchecked Exception(低級人禍):拒絕充氣洋芋片代碼
把指標指向 null 還硬要去呼叫方法,或是開了長度為 3 的陣列硬要去抓第 5 格,這徹頭徹尾是工程師自己的邏輯粗心。
如果連每一次物件呼叫、陣列存取、加減乘除,編譯器都要逼你包一層防護罩或層層往上呈報,那整份專案就會像「充氣洋芋片包裝」——空氣佔了 90%,真正的程式碼邏輯只有一點點。
對付這種低級失誤,最好的解法根本不是接住它,而是工程師自己回去把 if (obj != null) 寫好、把索引算對,踏踏實實修正程式!


上一篇
【Day 13】官方炸彈詞不達意?教你自製專屬炸彈,給系統一張客製化驗屍報告
下一篇
【Day 15】換包裝別把真兇給滅口!用 Exception Chaining 保留第一案發現場
系列文
大學以前只看過那隻貓?用白話文帶你從 Python 跨進 JavaScript 共 15 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言