Effective Java Item 57:縮小區域變數的使用範圍
整理 Effective Java 書中 Item 57: Minimize the scope of local variables 心得筆記
主旨
在 Java 裡,區域變數(local variables)應該只在真正需要的時候才宣告,並且讓它的「作用範圍」儘可能小。這樣做不僅能讓程式碼更清楚、易讀,也能有效降低 bug 發生的機率。
點出問題
有些人習慣在區塊(block)一開始就把所有變數宣告好,這是從 C 語言時代留下來的老習慣。但在 Java 裡,我們可以在任何合法語句出現的地方宣告變數,因此更應該在「第一次使用變數時」才宣告它。
為什麼這麼做比較好?
- 少一點雜訊:讀程式時不用一開始就記住所有變數是什麼。
- 降低出錯風險:變數作用範圍小,能避免在不該用的地方誤用。
- 強化 IDE 幫助:一些錯誤能在編譯時被偵測出來,而不是執行後才發現。
範例:for 迴圈的好處
// 推薦寫法:for-each 迴圈
for (Element e : c) {
doSomething(e);
}
或是需要 Iterator 的話:
// 傳統 for 迴圈(需要呼叫 iterator.remove() 時)
for (Iterator<Element> i = c.iterator(); i.hasNext(); ) {
Element e = i.next();
doSomething(e);
}
這樣的好處是,e 或 i 的作用範圍就只侷限在迴圈中,離開就無法再用它,也就不容易因為複製貼上出錯。
錯誤範例(使用 while 迴圈):
Iterator<Element> i = c.iterator();
while (i.hasNext()) {
doSomething(i.next());
}
// 這邊用了新的變數 i2,但錯用了 i
Iterator<Element> i2 = c2.iterator();
while (i.hasNext()) { // 錯誤!應該是 i2.hasNext()
doSomethingElse(i2.next());
}
上面的程式碼會 compile 也會執行,但會做錯事,因為第一個 i 還在作用範圍內。
如果你用的是 for 迴圈:
for (Iterator<Element> i = c.iterator(); i.hasNext(); ) {
...
}
// 這邊 i 不在作用範圍內,若寫錯會直接 compile error
for (Iterator<Element> i2 = c2.iterator(); i.hasNext(); ) { // 編譯錯誤!
...
}
這正是我們要的保護機制。
小技巧:for 裡一次宣告多個變數
for (int i = 0, n = expensiveComputation(); i < n; i++) {
// 使用 i,但避免每次都重新呼叫 expensiveComputation()
}
這樣做不但有效率,也讓 n 的作用範圍控制在迴圈內,不會留下多餘的變數污染區塊。
小節
縮小區域變數的作用範圍是乾淨、安全的程式設計好習慣:
- 在哪裡用,就在哪裡宣告。
- 盡量使用 for-each 或傳統 for 來控制變數作用範圍。
- 不夠資訊不能初始化時就延後宣告。
- 變數範圍小,IDE 抓 bug 更精準。
- 如果一個方法太多變數混在一起,可能代表該拆成多個小方法了。
這些原則乍看簡單,但長期下來會讓程式更乾淨、更容易維護。
Read other posts