Java 初學者常見疑問:三元運算子、字串串接與型別轉換一次搞懂【Thinking in Java筆記(2-4)】
剛開始學Java,看到 ? :
、+=
、(int)
這些奇怪符號就頭痛嗎? 這篇文章不是什麼艱澀的理論筆記,而是從「你到底為什麼會用到這些東西」的角度出發,讓你在實際寫程式時不再卡關
什麼是三元運算子(Ternary If-Else Operator)?我為什麼不用 if-else?
三元運算子是一種更短的寫法,用來根據條件決定要回傳哪個值
語法:
boolean 條件 ? 條件為 true 時的值 : 條件為 false 時的值
假設你想根據一個數字 i
的值來計算不同結果:
return (i < 10) ? i * 100 : i * 10;
這句話意思是:「如果 i
小於 10,回傳 i * 100
,否則回傳 i * 10
。」
你可以跟下面這段 if-else
比較:
int result;
if (i < 10) {
result = i * 100;
} else {
result = i * 10;
}
功能一樣,但三元運算子更簡潔
範例程式碼:
public class TernaryIfElse {
static int calculateUsingTernary(int i) {
return i < 10 ? i * 100 : i * 10;
}
static int calculateUsingIfElse(int i) {
if(i < 10)
return i * 100;
else
return i * 10;
}
public static void main(String[] args) {
print(calculateUsingTernary(9)); // 使用三元操作符計算,輸出: 900
print(calculateUsingTernary(10)); // 使用三元操作符計算,輸出: 100
print(calculateUsingIfElse(9)); // 使用標準if-else計算,輸出: 900
print(calculateUsingIfElse(10)); // 使用標準if-else計算,輸出: 100
}
} /* Output:
900
100
900
100
*/
提醒:
三元運算子適合用在「值的選擇」,像是簡單的 if-else
如果條件很複雜、有副作用、或需要做多件事,還是乖乖寫完整的if-else
比較好,別把自己繞進地獄
為什麼字串加法(+)那麼奇怪?
在 Java 裡用 +
號加字串很直覺,但也容易踩雷
你可能看過這種程式:
System.out.println("結果:" + 1 + 2);
你以為會輸出 結果:3
?錯!結果其實是:
結果:12
為什麼這樣?
Java 是從左到右執行的,而且只要有一邊是字串,後面的都會被轉成字串再做「字串串接」。所以:
- "結果:" + 1 → "結果:1"
- "結果:1" + 2 → "結果:12"
要改正這種情況,你應該這樣寫:
System.out.println("結果:" + (1 + 2)); // 輸出:結果:3
更完整範例:
public class StringOperators {
public static void main(String[] args) {
int x = 0, y = 1, z = 2;
String s = "x, y, z ";
System.out.println(s + x + y + z);
System.out.println(x + " " + s); // Converts x to a String
s += "(summed) = "; // Concatenation operator
System.out.println(s + (x + y + z));
System.out.println("" + x); // Shorthand for Integer.toString()
}
} /* Output:
x, y, z 012
0 x, y, z
x, y, z (summed) = 3
0
*/
關鍵觀念:
- 遇到
+
號,如果左邊是字串,Java 會自動把右邊轉成字串再做「拼接」 - 不管你是整數、布林值或浮點數,通通會變成字串
小技巧:
- 使用括號讓加法優先執行:
"合計:" + (a + b)
- 想強制轉成字串可以用:
String.valueOf(a)
或"" + a
- 想清楚「誰先變字串」可以幫助你少寫很多 bug
預防踩雷:
不要以為你在做加法,Java 有可能只是在幫你拼字串。尤其是 Debug 訊息那種 log 很多值的情況,一不小心就會拼錯
三、型別轉換運算子(Casting Operators)是什麼?為什麼有些需要強制轉型?
在程式中,有時需要將一種資料型別轉換為另一種。Java 通常會在安全的情況下自動幫你轉換,但當資料可能遺失或精度改變時,你就必須手動指定轉型方式,這就是「強制轉型」
範例:
public class Casting {
public static void main(String[] args) {
int i = 200;
long lng = (long)i; // 無需顯式轉換,因為 int 到 long 是 Widening
lng = i; // "Widening," so cast not really required
long lng2 = (long)200; // 直接將字面量轉為 long
lng2 = 200; // 擴展轉換,自動處理
// A "narrowing conversion":
i = (int)lng2; // Cast required,因為 long 到 int 可能導致資料丟失
}
}
窄化轉換與擴展轉換
- 窄化轉換(Narrowing Conversion):
- 大型別 → 小型別,例如 long → int
- 可能導致資料遺失,需要顯式轉型
- 擴展轉換(Widening Conversion):
- 小型別 → 大型別,例如 int → long
- 這是安全的,Java 會自動處理
2. 截斷與進位(Truncation and Rounding)
從浮點數轉換為整數時,小數會被直接「砍掉」,而非四捨五入
截斷範例:
public class CastingNumbers {
public static void main(String[] args) {
double above = 0.7, below = 0.4;
float fabove = 0.7f, fbelow = 0.4f;
print("(int)above: " + (int)above);
print("(int)below: " + (int)below);
print("(int)fabove: " + (int)fabove);
print("(int)fbelow: " + (int)fbelow);
}
} /* Output:
(int)above: 0
(int)below: 0
(int)fabove: 0
(int)fbelow: 0
*/
所有結果都是 0,因為它直接砍掉小數點之後的部分
如果你真的想要四捨五入?
使用 Math.round()
方法
public class RoundingNumbers {
public static void main(String[] args) {
double above = 0.7, below = 0.4;
float fabove = 0.7f, fbelow = 0.4f;
print("Math.round(above): " + Math.round(above));
print("Math.round(below): " + Math.round(below));
print("Math.round(fabove): " + Math.round(fabove));
print("Math.round(fbelow): " + Math.round(fbelow));
}
} /* Output:
Math.round(above): 1
Math.round(below): 0
Math.round(fabove): 1
Math.round(fbelow): 0
*/
3. 型別提升(Promotion)
當你在表達式中混用不同型別(如 int 與 long),Java 會自動將較小的型別轉為較大的型別來確保運算正確:
int + long → long
float + double → double
如果你想把這些運算結果放進比較小的型別變數裡,還是得自己強制轉型,否則編譯器會報錯
Java 為什麼沒有 sizeof
?我怎麼知道型別大小?
在 C/C++ 中,sizeof()
函數用於獲取資料型別或物件所佔用的記憶體大小,這在不同位元系統間的程式碼移植中非常重要
然而,Java 並未提供類似的 sizeof
運算子,原因如下:
- 固定的資料型別大小: Java 的基本資料型別在所有平台上都有固定的大小。例如,
int
永遠是 32 位元,long
永遠是 64 位元。 - 跨平台性: Java 是跨平台語言,不讓你碰底層
- 記憶體管理: Java 有自動垃圾回收機制,JVM 幫你管記憶體,自己不用算
所以 Java 沒有 sizeof()
是刻意設計,讓你更少煩惱平台差異
總結:看完你應該學會了...
主題 | 學到什麼 | 實際應用 |
---|---|---|
三元運算子 | 快速選擇值 | a > b ? a : b 這種判斷式 |
字串串接 | + 處理方式不直觀 | 記得用括號包數學運算 |
型別轉換 | 強制轉型與精度處理 | 理解何時該手動轉換與資料截斷風險 |
Java 沒 sizeof | JVM 幫你處理底層 | 不用煩記憶體管理 |
學 Java 的路很長,別讓這些基礎卡住你。如果這篇有幫助你理解一點點,記得把它存在書籤裡,或分享給也在學 Java 的朋友(他們也需要被拯救)
Comments ()