StringUtils.isNumeric(String str) 的一个坑(转)
在项目中遇到一处bug,调试的结果竟然是StringUtils.isNumeric(String str) 在捣鬼(采用的是org.apache.commons.lang.StringUtils),下面的代码是判断一个参数非空,且为整数:
if(StringUtils.isNumeric(str) && StringUtils.isNotBlank(str)){
// do sth
}
在简单不过的代码,却隐藏着bug !
因为如果 str = "-1"; StringUtils.isNumeric(str) 返回的是 false! 真是肯爹不偿命啊。
下面是测试:
public static void main(String[] args)
{
System.out.println(StringUtils.isNumeric("-1"));
}
运行结果:false
肯爹吧?用正则表达式实现不是很简单吗?怎么会这样,看了下源码:

public static boolean isNumeric(String str) {
if (str == null) {
return false;
}
int sz = str.length();
for (int i = 0; i < sz; i++) {
if (Character.isDigit(str.charAt(i)) == false) {
return false;
}
}
return true;
}

继续跳进去:
public static boolean isDigit(char ch) {
return isDigit((int)ch);
}
继续:

public static boolean isDigit(int codePoint) {
boolean bDigit = false;
if (codePoint >= MIN_CODE_POINT && codePoint <= FAST_PATH_MAX) {
bDigit = CharacterDataLatin1.isDigit(codePoint);
} else {
int plane = getPlane(codePoint);
switch(plane) {
case(0):
bDigit = CharacterData00.isDigit(codePoint);
break;
case(1):
bDigit = CharacterData01.isDigit(codePoint);
break;
case(2):
bDigit = CharacterData02.isDigit(codePoint);
break;
case(3): // Undefined
case(4): // Undefined
case(5): // Undefined
case(6): // Undefined
case(7): // Undefined
case(8): // Undefined
case(9): // Undefined
case(10): // Undefined
case(11): // Undefined
case(12): // Undefined
case(13): // Undefined
bDigit = CharacterDataUndefined.isDigit(codePoint);
break;
case(14):
bDigit = CharacterData0E.isDigit(codePoint);
break;
case(15): // Private Use
case(16): // Private Use
bDigit = CharacterDataPrivateUse.isDigit(codePoint);
break;
default:
// the argument's plane is invalid, and thus is an invalid codepoint
// bDigit remains false;
break;
}
}
return bDigit;
}

在下面一步失败:
static boolean isDigit(int ch) {
int type = getType(ch);
return (type == Character.DECIMAL_DIGIT_NUMBER);
}
也就是说他的实现完全没有考虑到 - + 前缀的问题,这不是傻叉吗?
下面的结果都是 false:
public static void main(String[] args)
{
System.out.println(StringUtils.isNumeric("-1"));
System.out.println(StringUtils.isNumeric("+1"));
}
这是他的方法注释:

Checks if the String contains only unicode digits. A decimal point is not a unicode digit and returns false.
null will return false. An empty String ("") will return true.
StringUtils.isNumeric(null) = false
StringUtils.isNumeric("") = true
StringUtils.isNumeric(" ") = false
StringUtils.isNumeric("123") = true
StringUtils.isNumeric("12 3") = false
StringUtils.isNumeric("ab2c") = false
StringUtils.isNumeric("12-3") = false
StringUtils.isNumeric("12.3") = false
Parameters:
str the String to check, may be null
Returns:
true if only contains digits, and is non-null

只能包含 unicode 的数字, +, -, . 三者都不能算作是unicode 数字。
http://www.cnblogs.com/digdeep/p/4207097.html
StringUtils.isNumeric(String str) 的一个坑(转)的更多相关文章
- 肯爹的 StringUtils.isNumeric(String str)
在项目中遇到一处bug,调试的结果竟然是StringUtils.isNumeric(String str) 在捣鬼(采用的是org.apache.commons.lang.StringUtils),下 ...
- equals变量在前面或者在后面有什么区别吗?这是一个坑点
我就不废话那么多,直接上代码: package sf.com.mainTest; public class Test { public static void main(String[] args) ...
- StringUtils.isNumeric()的特殊点
String str = "-1"; StringUtils.isNumeric(str) 返回的是false StringUtils.isNumeric()方法在判断字符串是否是 ...
- 关于String str =new String("abc")和 String str = "abc"的比较
String是一个非常常用的类,应该深入的去了解String 如: String str =new String("abc") String str1 = "abc&qu ...
- 经典String str = new String("abc")内存分配问题
出自:http://blog.csdn.net/ycwload/article/details/2650059 今天要找和存储管理相关的一些知识,网上搜了半天也没有找到完善的(30%的程度都不到),没 ...
- PHP中逻辑运算符and/or与||/&&的一个坑
我原来以为PHP中的and和&&是一样的, 只是写法上为了可读性和美观, 事实上我错了. 这里面深藏了一个坑! 看以下代码: $bA = true; $bB = false; $b1 ...
- compareTo(String str)与compareToIgnoreCase(String str)
一.compareTo(String str)方法 返回值:如果参数字符串等于此字符串,则返回值 0:如果此字符串按字典顺序小于字符串参数,则返回一个小于 0 的值:如果此字符串按字典顺序大于字符串参 ...
- 困扰多日的C#调用Haskell问题竟然是Windows的一个坑
最近一直被C#调用Haskell时的“尝试读取或写入受保护的内存”问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C# ...
- String str=new String("a")和String str = "a"有什么区别?
问:String str=new String("a")和String str = "a"有什么区别? 答:String str = "a" ...
随机推荐
- 如何高效地向Redis插入大量的数据(转)
最近有个哥们在群里问,有一个日志,里面存的是IP地址(一行一个),如何将这些IP快速导入到Redis中. 我刚开始的建议是Shell+redis客户端. 今天,查看Redis官档,发现文档的首页部分( ...
- cmake编译时遇到的问题解决
编译cmake首先须要gcc环境,能够运行 gcc --version命令看看. 假设没有,能够使用yum或从cd中进行安装,此处是在虚拟机中从cd中进行安装.将cd链接到虚拟机都会吧,此处略去,.. ...
- freemarker自己定义标签(二)
freemarker自己定义标签 1.自己定义标签 通过自己定义标签,写一个反复指定字符串 2.实现源代码 <html> <head> <meta http-equiv= ...
- Patch to solve sqlite3_int64 error when building Python 2.7.3 on RHEL/CentOS
Patch to solve sqlite3_int64 error when building Python 2.7.3 on RHEL/CentOS Patch to solve sqlite3_ ...
- 每日一小练——高速Fibonacci数算法
上得厅堂,下得厨房,写得代码,翻得围墙,欢迎来到睿不可挡的每日一小练! 题目:高速Fibonacci数算法 内容:先说说Fibonacci数列,它的定义是数列:f1,f2....fn有例如以下规律: ...
- A Game of Thrones(8) - Bran
The hunt left at dawn. The king wanted wild boar at the feast tonight. Prince Joffrey rode with his ...
- Eclipse中的Maven项目报Unbound classpath variable错误
今天更新了最新版的Eclipse luna 4.4版本号,svn更新了项目后,系统一直报错,经查看在Problems窗体中发现一堆错误.提演示样例如以下: Unbound classpath ...
- linux LNMP自动安装脚本
#!/bin/bashsoft_dir="/home/soft"config_dir="/home/config"httpd="httpd-2.0.5 ...
- Java学习文件夹
每天进步一点点,先研究一门语言深入研究下去.
- SWT的TreeVierer的使用
先看一下效果图: 代码结构是这样的: 好的,现在看一下代码: package model; import java.util.List; public interface ITree { public ...