最简单但有限的方法:Double.parseDouble() 或 Integer.parseInt()
这是最直观、最简单的方法,适用于基本数字格式。

原理:尝试将 String 解析为 double 或 int,如果解析失败(即字符串不是合法的数字格式),会抛出 NumberFormatException 异常,我们可以利用这个异常来判断。
示例代码
public class NumberUtils {
// 判断是否为整数
public static boolean isInteger(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
// 判断是否为浮点数
public static boolean isDouble(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static void main(String[] args) {
String intStr1 = "123";
String intStr2 = "123.45";
String intStr3 = "abc";
String intStr4 = ""; // 空字符串
String intStr5 = null;
System.out.println("'" + intStr1 + "' is an integer? " + isInteger(intStr1)); // true
System.out.println("'" + intStr2 + "' is an integer? " + isInteger(intStr2)); // false
System.out.println("'" + intStr3 + "' is an integer? " + isInteger(intStr3)); // false
System.out.println("'" + intStr4 + "' is an integer? " + isInteger(intStr4)); // false
System.out.println("null is an integer? " + isInteger(intStr5)); // false
System.out.println("------------------------------------");
String doubleStr1 = "123.45";
String doubleStr2 = "123";
String doubleStr3 = "1.23e10"; // 科学计数法
String doubleStr4 = " -123.45 "; // 带空格
System.out.println("'" + doubleStr1 + "' is a double? " + isDouble(doubleStr1)); // true
System.out.println("'" + doubleStr2 + "' is a double? " + isDouble(doubleStr2)); // true
System.out.println("'" + doubleStr3 + "' is a double? " + isDouble(doubleStr3)); // true
System.out.println("'" + doubleStr4 + "' is a double? " + isDouble(doubleStr4)); // false (因为parseDouble不处理前后空格)
}
}
优点:
- 代码简单:易于理解和实现。
- 功能强大:
Double.parseDouble()支持整数、小数、科学计数法(如23e10)、正负号等。
缺点:
- 性能稍差:异常处理机制(try-catch)在 Java 中是有性能开销的,如果需要频繁判断,这会成为瓶颈。
- 对空格敏感:
" 123 "这样的字符串会返回false,因为它不希望解析前后有空格。 - 范围限制:对于
Integer.parseInt(),如果数字超出int的范围(约 ±21亿),会抛出异常,返回false。 - 不够精确:无法区分
"123"是整数还是浮点数。
性能更优的方法:正则表达式
如果你需要在一个循环中大量判断字符串,或者想更精确地控制数字的格式,正则表达式是更好的选择。
原理:定义一个匹配数字模式的正则表达式,然后用 String.matches() 方法去匹配。
示例代码
public class RegexNumberUtils {
// 判断是否为整数(包括正负号)
public static boolean isIntegerByRegex(String str) {
if (str == null) {
return false;
}
// ^[+-]?\\d+$ 解释:
// ^ 字符串开始
// [+-]? 可选的正号或负号
// \\d+ 一个或多个数字 (0-9)
// $ 字符串结束
return str.matches("^[+-]?\\d+$");
}
// 判断是否为浮点数(包括正负号、小数点、科学计数法)
public static boolean isDoubleByRegex(String str) {
if (str == null) {
return false;
}
// ^[+-]?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$ 解释:
// ^[+-]?\\d+ 可选正负号 + 一个或多个整数部分
// (\\.\\d+)? 可选的小数部分 (一个点 + 一个或多个数字)
// ([eE][+-]?\\d+)? 可选的科学计数法部分 (e/E + 可选正负号 + 一个或多个数字)
// $
return str.matches("^[+-]?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$");
}
public static void main(String[] args) {
String num1 = "123";
String num2 = "-456";
String num3 = "+789";
String num4 = "123.45";
String num5 = "1.23e10";
String num6 = "1.23E-5";
String num7 = "abc";
String num8 = "123.";
System.out.println("Using Regex:");
System.out.println("'" + num1 + "' is a number? " + isDoubleByRegex(num1)); // true
System.out.println("'" + num2 + "' is a number? " + isDoubleByRegex(num2)); // true
System.out.println("'" + num3 + "' is a number? " + isDoubleByRegex(num3)); // true
System.out.println("'" + num4 + "' is a number? " + isDoubleByRegex(num4)); // true
System.out.println("'" + num5 + "' is a number? " + isDoubleByRegex(num5)); // true
System.out.println("'" + num6 + "' is a number? " + isDoubleByRegex(num6)); // true
System.out.println("'" + num7 + "' is a number? " + isDoubleByRegex(num7)); // false
System.out.println("'" + num8 + "' is a number? " + isDoubleByRegex(num8)); // false (根据我们的正则,.后面必须有数字)
}
}
优点:
- 性能高:正则表达式匹配通常比异常捕获快,尤其是在循环中。
- 灵活性强:可以精确控制匹配的格式,例如只匹配特定格式的数字。
- 不依赖异常:避免了异常处理的性能开销。
缺点:
- 正则表达式复杂:对于复杂的数字格式(如科学计数法),正则表达式会变得难以阅读和维护。
- 需要学习成本:需要熟悉正则表达式的语法。
最严谨的方法:Apache Commons Lang NumberUtils
在实际项目中,强烈推荐使用成熟的第三方库,Apache Commons Lang 是一个非常流行的 Java 工具库,其中的 NumberUtils 类提供了非常完善的数字判断功能。
依赖: 你需要添加 Maven 依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version> <!-- 使用最新版本 -->
</dependency>
核心方法:
NumberUtils.isParsable(String str): 判断字符串是否可以被解析为任何一种 Java 数字类型(int,long,float,double等)。这是最常用、最推荐的方法。NumberUtils.isCreatable(String str): 功能与isParsable几乎一样,官方文档建议优先使用isParsable。
示例代码
import org.apache.commons.lang3.math.NumberUtils;
public class CommonsLangNumberUtils {
public static void main(String[] args) {
String str1 = "123";
String str2 = "123.45";
String str3 = "1,234"; // 千位分隔符,NumberUtils.isParsable() 返回 false
String str4 = "1.23e10";
String str5 = " -123.45 ";
String str6 = "abc";
String str7 = ""; // 空字符串
String str8 = null;
// NumberUtils.isParsable() 是最推荐的方法
// 它能处理整数、小数、科学计数法、正负号
// 但不能处理带空格或千位分隔符的字符串
System.out.println("Using Apache Commons Lang NumberUtils.isParsable():");
System.out.println("'" + str1 + "' is parsable? " + NumberUtils.isParsable(str1)); // true
System.out.println("'" + str2 + "' is parsable? " + NumberUtils.isParsable(str2)); // true
System.out.println("'" + str3 + "' is parsable? " + NumberUtils.isParsable(str3)); // false
System.out.println("'" + str4 + "' is parsable? " + NumberUtils.isParsable(str4)); // true
System.out.println("'" + str5 + "' is parsable? " + NumberUtils.isParsable(str5)); // false (因为有空格)
System.out.println("'" + str6 + "' is parsable? " + NumberUtils.isParsable(str6)); // false
System.out.println("'' is parsable? " + NumberUtils.isParsable(str7)); // false
System.out.println("null is parsable? " + NumberUtils.isParsable(str8)); // false
}
}
优点:
- 功能强大且稳定:经过大量项目验证,非常可靠。
- 代码简洁:一行代码搞定,无需自己写
try-catch或正则表达式。 - 可读性好:
NumberUtils.isParsable(str)的意图非常明确。
缺点:
- 引入外部依赖:需要在项目中添加第三方库的依赖。
总结与推荐
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
try-catch |
简单直观,支持标准数字格式 | 性能开销,对空格敏感,范围限制 | 快速原型、简单判断、不追求极致性能 |
| 正则表达式 | 性能高,灵活可控 | 正则表达式复杂,有学习成本 | 需要大量循环判断,或需要自定义数字格式 |
NumberUtils.isParsable() |
功能强大、稳定、代码简洁、可读性好 | 需要引入第三方库 | (强烈推荐)生产环境、企业级应用 |
最终建议:
- 如果你正在开发一个企业级或生产级的应用,请毫不犹豫地选择 Apache Commons Lang 的
NumberUtils.isParsable(),这是最专业、最可靠、最省心的方案。 - 如果你只是写一个小的工具类或学习示例,并且不想引入外部依赖,
try-catch方法 是一个不错的选择,简单直接。 - 如果你对性能有极高要求,或者需要匹配非常特殊、自定义的数字格式,那么可以考虑 正则表达式,但务必花时间写对和测试你的正则表达式。
