Java 中 `int` 轉 `String` 有三種常見寫法:i + ""、String.valueOf(i)、Integer.toString(i)。實測 10 萬次循環,耗時對比:
i + "" : 257 ms String.valueOf(i) : 140 ms Integer.toString(i) : 159 ms
結論:+ "" 明顯較慢,後兩者接近。為什麼?深入 JDK 源碼揭秘。
public static String valueOf(int i) {
return Integer.toString(i); // 直接委託
}
public static String toString(int i) {
return Integer.toString(i, 10); // 基數 10
}
// 核心實現
static String toString(int i, int radix) {
if (radix == 10) return toString(i); // 內部調用
// ... 其他進制
}
// 最終落點:Integer.toString(int) -> Integer.toUnsignedString0(i)
static String toString(int i) {
return toUnsignedString0(i);
}
實際核心邏輯在 Integer.toUnsignedString0(JDK 8+)或 Integer.getChars(舊版),採用 **查表法 + 分治算法** 高效轉換。
DIGITS/TENS/ONES,O(1) 直接查表返回。0x51EB851F 乘法代替除法(q = (i * 0x51EB851F) >>> 37),餘數 r = i - 100*q。r (0~99) 再查表獲取兩位字符。Integer.MIN_VALUE 直接返回 "-2147483648",否則加負號前綴。i + "" 較慢?編譯器將 i + "" 轉為:
new StringBuilder().append("").append(i).toString()
額外開銷:
1. `new StringBuilder()` 物件分配。
2. `append("")` 無意義操作。
3. `append(int)` 內部仍調用 `Integer.getChars`(同核心算法),但多了 `StringBuilder` 擴容、複製、`toString()` 新建 `String` 物件。
4. JIT 雖可優化標量替換,但不如靜態方法直接返回字符串穩定。
i + "" : 199 ms String.valueOf(i) : 7 ms Integer.toString(i) : 6 ms
小數命中快速查表路徑,+ "" 的物件分配開銷佔比更高。
Integer.toString(i) 或 String.valueOf(i):語意清晰、零額外分配、效能最優。i + "":雖然寫法簡短,但在高頻調用、日誌拼接、序列化等熱點路徑有可測量開銷。String.format / DecimalFormat:如千分位、補零等複雜格式。Long.toString(l)、Double.toString(d) 等均提供高效靜態方法。Boolean.toString(b) 返回共享常量 "true"/"false",極快。