字串處理是 Java 開發最高頻操作,錯誤的判空順序會導致 `NullPointerException`,數字檢查方式選擇影響效能與正確性。
String selection = getInput();
// ✅ 正確:短路邏輯,先檢 null 再呼叫 equals
if (selection != null && !selection.isEmpty()) {
// 安全使用 selection
}
// ❌ 錯誤:selection 為 null 時直接拋 NPE
if (!selection.isEmpty() && selection != null) { ... }
// Java 6+ 推薦用 isEmpty() 而非 equals(""),語意更清晰、效能略優
// Java 11+ 可用 isBlank() 同時排除空白字元
if (selection != null && !selection.isBlank()) { ... }
| 方案 | 程式碼 | 優點 | 缺點 |
|---|---|---|---|
| Character.isDigit 迴圈 |
public static boolean isNumeric(String s) {
if (s == null || s.isEmpty()) return false;
for (int i = 0; i < s.length(); i++) {
if (!Character.isDigit(s.charAt(i))) return false;
}
return true;
}
| 無建立物件、效能最佳、無正則開銷 | 僅支援 ASCII 0-9,不含負號、小數點、全形數字 |
| 正則表達式 |
public static boolean isNumeric(String s) {
return s != null && s.matches("\\d+");
// 或預編譯 Pattern: Pattern.compile("\\d+").matcher(s).matches();
}
| 語意清晰、可擴充 (如 `^-?\\d+(\\.\\d+)?$` 支援負數/小數) | 編譯/匹配有開銷、頻繁呼叫需快取 Pattern |
| ASCII 碼比對 |
public static boolean isNumeric(String s) {
if (s == null) return false;
for (char c : s.toCharArray()) {
if (c < '0' || c > '9') return false;
}
return true;
}
| 原理直觀、無 API 依賴 | 本質同方案一、易寫錯邊界 |
// 使用 Java 內建解析器 (最可靠)
public static boolean isParsableNumber(String s) {
if (s == null || s.isBlank()) return false;
try {
new java.math.BigDecimal(s); // 或 Double.parseDouble / Long.parseLong
return true;
} catch (NumberFormatException e) {
return false;
}
}
// 正則支援完整數字格式
private static final Pattern NUMBER_PATTERN = Pattern.compile(
"^[-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?$"
);
public static boolean isNumericRegex(String s) {
return s != null && NUMBER_PATTERN.matcher(s).matches();
}
// Commons Lang 3
StringUtils.isNumeric(CharSequence cs) // 僅 0-9
StringUtils.isNumericSpace(CharSequence cs) // 允許空白
NumberUtils.isCreatable(CharSequence cs) // 支援負號、小數、0xFF、077 等
// Guava
CharMatcher.DIGIT.matchesAllOf(cs) // 僅 0-9
str != null && !str.isEmpty()` (或 `isBlank()`),順序不可顛倒。Character.isDigit` 迴圈或預編譯 `Pattern`。BigDecimal` 解析或完整正則。