在项目中遇到一处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) 的一个坑(转)的更多相关文章

  1. 肯爹的 StringUtils.isNumeric(String str)

    在项目中遇到一处bug,调试的结果竟然是StringUtils.isNumeric(String str) 在捣鬼(采用的是org.apache.commons.lang.StringUtils),下 ...

  2. equals变量在前面或者在后面有什么区别吗?这是一个坑点

    我就不废话那么多,直接上代码: package sf.com.mainTest; public class Test { public static void main(String[] args) ...

  3. StringUtils.isNumeric()的特殊点

    String str = "-1"; StringUtils.isNumeric(str) 返回的是false StringUtils.isNumeric()方法在判断字符串是否是 ...

  4. 关于String str =new String("abc")和 String str = "abc"的比较

    String是一个非常常用的类,应该深入的去了解String 如: String str =new String("abc") String str1 = "abc&qu ...

  5. 经典String str = new String("abc")内存分配问题

    出自:http://blog.csdn.net/ycwload/article/details/2650059 今天要找和存储管理相关的一些知识,网上搜了半天也没有找到完善的(30%的程度都不到),没 ...

  6. PHP中逻辑运算符and/or与||/&&的一个坑

    我原来以为PHP中的and和&&是一样的, 只是写法上为了可读性和美观, 事实上我错了. 这里面深藏了一个坑! 看以下代码: $bA = true; $bB = false; $b1  ...

  7. compareTo(String str)与compareToIgnoreCase(String str)

    一.compareTo(String str)方法 返回值:如果参数字符串等于此字符串,则返回值 0:如果此字符串按字典顺序小于字符串参数,则返回一个小于 0 的值:如果此字符串按字典顺序大于字符串参 ...

  8. 困扰多日的C#调用Haskell问题竟然是Windows的一个坑

    最近一直被C#调用Haskell时的“尝试读取或写入受保护的内存”问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C# ...

  9. String str=new String("a")和String str = "a"有什么区别?

    问:String str=new String("a")和String str = "a"有什么区别? 答:String str = "a" ...

随机推荐

  1. Struts工作机制图+OGNL+EL+值栈(Map,对象栈)

    struts 值栈  通过get set方法 方便的获取,设置属性值      比如从jsp页面传来的參数...从Action设置jsp所要回显的内容 注意EL表达式,struts2对request进 ...

  2. POJ 2318 TOYS(计算几何)

    跨产品的利用率推断点线段向左或向右,然后你可以2分钟 代码: #include <cstdio> #include <cstring> #include <algorit ...

  3. Rudiments 0.42 发布,C++ 常用工具包 - 开源中国社区

    Rudiments 0.42 发布,C++ 常用工具包 - 开源中国社区 Rudiments 0.42 发布,C++ 常用工具包

  4. 在Windows如何解决下Cocos2d-x示例代码TestCpp我找不到lib问题库文件

    遇到此问题,首先确定失踪的库文件,然后找到文件夹,库文件. 在编制Cocos2d-x在TestCpp工程,提示缺少lib文件,共同拥有下面2种可靠解决方式: 1.在Cocos2d-x的根文件夹Debu ...

  5. VMware vSphere服务器虚拟化实验十一高可用性之三Fault Tolerance

                                                                VMware vSphere服务器虚拟化实验十一高可用性之三Fault Tole ...

  6. Android SDK r23

    SDK Tools Only Platform Package Size MD5 Checksum Windows 32 & 64-bit android-sdk_r23-windows.zi ...

  7. SQL Syscolumns

    每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行.该表位于每个数据库中. 列名 数据类型 描述 name sysname 列名或过程参数的名称. id int 该列所属的表对象 I ...

  8. C#文件流写入方法

    stream为服务端接收的文件流 var bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); // 设置当前流的 ...

  9. HDOJ 3516 Tree Construction

    四边形优化DP Tree Construction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  10. iOS开发人员必看的精品资料(100个)

    目录下载地址:http://down.51cto.com/data/416672 附件预览如下: iOS游戏开发之Unity3D引擎系列 http://down.51cto.com/zt/399 iP ...