類型轉換是 Java 程式設計中的基礎且高頻操作。本文系統整理基本類型、包裝類、字串之間的相互轉換方式,並分析各方法的效能差異與適用場景。
| 目標類型 | 推薦方法 | 備選方法 | 異常處理 |
|---|---|---|---|
| int | Integer.parseInt(str) | Integer.valueOf(str).intValue() | NumberFormatException |
| long | Long.parseLong(str) | Long.valueOf(str).longValue() | NumberFormatException |
| double | Double.parseDouble(str) | Double.valueOf(str).doubleValue() | NumberFormatException |
| float | Float.parseFloat(str) | Float.valueOf(str).floatValue() | NumberFormatException |
| boolean | Boolean.parseBoolean(str) | Boolean.valueOf(str).booleanValue() | 不拋異常,非 true 皆 false |
| byte | Byte.parseByte(str) | Byte.valueOf(str).byteValue() | NumberFormatException |
| short | Short.parseShort(str) | Short.valueOf(str).shortValue() | NumberFormatException |
進制轉換:Integer.parseInt("FF", 16) → 255(支援 2-36 進制)
| 來源類型 | 方法一(推薦) | 方法二 | 方法三 |
|---|---|---|---|
| int | String.valueOf(i) | Integer.toString(i) | "" + i |
| long | String.valueOf(l) | Long.toString(l) | "" + l |
| double | String.valueOf(d) | Double.toString(d) | "" + d |
| float | String.valueOf(f) | Float.toString(f) | "" + f |
| boolean | String.valueOf(b) | Boolean.toString(b) | "" + b |
效能建議:String.valueOf() 內部直接調用對應的 toString(),且能處理 null 物件(回傳 "null" 字串),是最安全通用的選擇。
// 裝箱:基本類型 → 包裝類 Integer i = 100; // 相當於 Integer.valueOf(100) Double d = 3.14; // 相當於 Double.valueOf(3.14) // 拆箱:包裝類 → 基本類型 int val = i; // 相當於 i.intValue() double val2 = d; // 相當於 d.doubleValue()
// 手動裝箱 Integer i1 = Integer.valueOf(100); // 使用快取池 [-128, 127] Integer i2 = new Integer(100); // 每次建立新物件(不推薦) // 手動拆箱 int val = i1.intValue();
Integer a = 100; Integer b = 100; System.out.println(a == b); // true(快取池內) Integer c = 200; Integer d = 200; System.out.println(c == d); // false(超出快取範圍,新建物件) // 正確比較方式 System.out.println(c.equals(d)); // true
// String → sql.Date(格式必須 yyyy-MM-dd)
java.sql.Date sqlDate = java.sql.Date.valueOf("2024-01-15");
// sql.Date → String
String dateStr = sqlDate.toString(); // "2024-01-15"
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Date → String
String formatted = sdf.format(new Date());
// String → Date
Date parsed = sdf.parse("2024-01-15 14:30:00");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// LocalDateTime → String
String formatted = LocalDateTime.now().format(formatter);
// String → LocalDateTime
LocalDateTime parsed = LocalDateTime.parse("2024-01-15 14:30:00", formatter);
// 互轉 java.util.Date
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime ldt = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
byte → short → int → long → float → double
int i = 10; double d = i; // 自動提升為 10.0 // char 特殊規則 char c = 'A'; int charInt = c; // 自動轉為 ASCII/Unicode 碼值 65
double d = 3.14159; int i = (int) d; // 3,截斷小數部分 long l = 10000000000L; int overflow = (int) l; // 溢位,結果不可預期
public class TypeConverter {
/** 安全轉換為 Integer,失敗回傳預設值 */
public static Integer toInteger(Object obj, Integer defaultValue) {
if (obj == null) return defaultValue;
if (obj instanceof Integer) return (Integer) obj;
if (obj instanceof Number) return ((Number) obj).intValue();
try {
return Integer.parseInt(obj.toString().trim());
} catch (NumberFormatException e) {
return defaultValue;
}
}
/** 安全轉換為 Long */
public static Long toLong(Object obj, Long defaultValue) {
if (obj == null) return defaultValue;
if (obj instanceof Long) return (Long) obj;
if (obj instanceof Number) return ((Number) obj).longValue();
try {
return Long.parseLong(obj.toString().trim());
} catch (NumberFormatException e) {
return defaultValue;
}
}
/** 格式化 Double 保留指定小數位 */
public static String formatDouble(double value, int decimalPlaces) {
return String.format("%." + decimalPlaces + "f", value);
}
}
equals(),避免 == 比較物件參考BigDecimal.valueOf(double) 或字串建構子,避免 new BigDecimal(0.1) 精度問題掌握類型轉換的核心在於理解:基本類型與包裝類的裝箱拆箱機制、字串解析的異常處理、日期時間 API 的演進,以及精度敏感場景下 BigDecimal 的正確使用。