iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
JavaScript

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

【Day 11】別讓炸彈一路砸到 main()!用 throw 與 throws 建立清楚的通報機制

  • 分享至 

  • xImage
  •  

昨天我們在主程式蓋好了 try-catch 防爆實驗室,專門用來接住外界亂丟進來的例外炸彈。
但不知道你有沒有想過一個問題:防爆室裡接到的那些炸彈,到底是誰製造、又是誰丟出來的?
很多時候,錯誤根本不是電腦底層當機,而是我們自己寫的類別在門口「抓到了現行犯」!為了防止整個系統被荒謬的髒資料污染,我們決定當場拉響警報、親手引爆這顆炸彈!
在 Java 裡,就有一對搭檔負責處理這種事,就是 throw(丟出炸彈) 與 throws(門口貼警告)。

  1. 為什麼要自找麻煩?主動引爆的「防腐哲學」
    想像一下之前寫過的圓形類別 Circle:
    public void setRadius(double radius) {
    this.radius = radius; // 萬一有人傳進來的是 -5 呢?
    }
    如果有人在主程式寫下 c.setRadius(-5);,站在 Java 的語法規則來看:
    -5 算一個合法的浮點數(符合 double 規範)
    編譯器會不會抗議?完全不會,它還覺得你寫得很棒。
    但這正是最恐怖的地方——語法合法(編譯器覺得沒毛病)但現實生活卻完全不合理!
    世界上哪裡找得到「半徑負 5 公分」的圓形?
    如果放任這個 -5 悄悄溜進系統,後面算面積、算圓周、畫圖形,整份程式碼就會一路錯到底,最後在幾百行後引發莫名其妙的靈異現象。
    與其讓這筆髒資料在系統裡慢性發炎,不如及早抓包、當場處決。

  2. throw(單數、動詞):「親手造出一顆炸彈丟出去!」
    public void setRadius(double radius) {
    // 1. 守門員安檢:抓到違法數值現行犯!
    if (radius < 0) {
    // 2. new 出一顆專門對付違法數值的炸彈,雙引號內寫好臨終遺言,丟出去!
    throw new IllegalArgumentException("半徑必須大於零!");
    }

    // 3. 只要上面引爆了,這行就永遠不會跑!< 0的半徑不會進來存檔!
    this.radius = radius;
    }
    new IllegalArgumentException(...) 是在記憶體當場組裝出「不合法參數炸彈」實體
    括號裡是寫給人看的「臨終遺言」:
    字串裡的文字就是死因報告。它會跟著變數 e 一路送到外面的急救站,讓後續接招的人印出 e.getMessage() 時,能一秒看懂到底是誰在胡鬧。
    一旦 throw 發動,這個方法當場緊急剎車、後面所有程式碼通通停擺!

  3. throws:出一張嘴,門口貼「高壓危險,後果自負」警告牌
    如果你在程式碼裡藏了隨時可能引爆的機制,必須在方法的門口(宣告列)大字公告。

// 門口昭告天下:進來呼叫本方法的人注意,這裡可能飛出 IllegalArgumentException!
public void setRadius(double radius) throws IllegalArgumentException {
if (radius < 0) {
throw new IllegalArgumentException("半徑不能為負數!");
}
this.radius = radius;
}
throws 是事前預告(防患未然):警告所有打算呼叫它的外部程式(例如 Main):
「我這裡頭有未爆彈檢驗關卡!想叫我做事,你們外面最好自備 try-catch 防爆箱,否則炸死自己概不負責!」
被宣告 throws 的方法本身:它只負責工作與拉警報,裡面通常不寫 try-catch。它在門口掛了 throws 牌子,就代表它已經跟編譯器報備過:「我不想自己處理這個炸彈,我要丟出去」。 使用它的那一層(例如 Main):因為它想使喚這個危險方法做事,所以是它自己要準備 try-catch 來包住這個呼叫動作。
責任甩鍋(向上呈報):
基層方法(例如 setRadius)只負責技術性抓包並大喊「爆炸啦!」。至於外面是要重開對話框、要使用者重打、還是直接報警?基層員工不管,責任全部往上推給呼叫他的主管(外層)去煩惱!
員工(方法 A):執行時發現資料不對,但它只是一個算數學的小函式,它根本不知道目前系統是在跑網頁、手機 App、還是控制台終端機,它無權決定該彈跳視窗還是重填。所以它選擇 throw 向上呈報。
長官(呼叫方法 A 的方法 B):如果方法 B 接到了,
方法 B 可以選擇:自己用 try-catch 扛下來:決定因應對策(例如彈出提示視窗請使用者重打)
繼續往上丟(自己門口也寫 throws):呈報給上一級主管

一句話記住:
throws 是方法的「甩鍋宣告」;誰寫程式碼去「呼叫」這個方法,誰的身上就背負了準備 try-catch 拆炸彈的責任


上一篇
【Day 10】使用者不按牌理出牌?帶上 try-catch 防爆小組,程式絕不輕易死給你看
下一篇
【Day 12】佔著茅坑不拉屎?別讓資源洩漏拖垮系統
系列文
大學以前只看過那隻貓?用白話文帶你從 Python 跨進 JavaScript 共 15 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言