在 Java 底層,資料操作皆透過運算子完成。然而某些運算子行為與直覺不同,極易導致難以察覺的 Bug。本文深度解析四大高風險運算子場景。
基本型別採值傳遞,物件則傳遞參考。這意味著物件指派後,兩個變數指向同一記憶體位址,任一修改皆影響彼此。
class A { int a; }
public class AssignmentDemo {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
a1.a = 1;
a2.a = 2;
System.out.println("a1: " + a1.a); // 1
System.out.println("a2: " + a2.a); // 2
a1 = a2; // a1 現在指向 a2 同一物件
System.out.println("a1: " + a1.a); // 2
System.out.println("a2: " + a2.a); // 2
a1.a = 99; // 修改共享物件
System.out.println("a1: " + a1.a); // 99
System.out.println("a2: " + a2.a); // 99 ← 同步改變!
a2.a = 100;
System.out.println("a1: " + a1.a); // 100
System.out.println("a2: " + a2.a); // 100
}
}
Java 整數相除結果仍為整數,小數部分直接截斷,非四捨五入。
int a = 3, b = 2;
System.out.println(a / b); // 輸出 1,非 1.5
需轉型為 double 或使用 BigDecimal 保留精度。
基本型別比較值,物件比較參考位址。即使內容相同,不同實例也回傳 false。
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1 == n2); // false - 不同物件實例
System.out.println(n1 != n2); // true
Integer n3 = n1, n4 = n2;
System.out.println(n3 == n4); // false
n4 = n1; // 同一參考
System.out.println(n3 == n4); // true
正確做法:使用 .equals() 比較內容,或善用自動裝箱快取機制(-128 到 127)。
異於 C/C++,Java 不允許整數直接作為布林表達式。while(1) 編譯失效,必須寫 while(true)。此設計強制型別安全,避免隱性轉換錯誤。
Objects.equals() (Java 7+)final 減少可變狀態