在项目中遇到一处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. QML性能

    1) Limit JavaScript a) inline JavaScript:  内联的JavaScript方法;   1. 将js方法放置在Element内部;  2. 尝试将语句写在一行内; ...

  2. ruby on rails创建的页面訪问很慢

    ruby on rails创建的页面訪问很慢 用rvm安装的ruby1.9.3 解决:cd ~/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/webrick v ...

  3. hdu 4274 Spy&#39;s Work(水题)

    Spy's Work Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. 【iOS开发-76】Private Contacts案例:导航控制器使用、数据传递、第三方类库使用、tableViewCell的加入删除、数据存储等

    (1)效果 (2)源码与第三方类库下载 http://download.csdn.net/detail/wsb200514/8155979 (3)总结 --导航控制器,能够直接用代码的push和pop ...

  5. RoboGuice注入框架简单应用

    1.设置Activity为RoboActivity; 2.设置界面@ContentView(int resId) 3.使用@InjectView(int resId)反射组件 4.使用@Inject ...

  6. Nlog配置文件

    <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nl ...

  7. WebKit爬虫

    https://github.com/emyller/webkitcrawler 一个开源的项目,可以快速入门. http://spiderformysql.com/ http://crawl.gro ...

  8. AJAX POST请求中參数以form data和request payload形式在servlet中的获取方式

    HTTP请求中,假设是get请求,那么表单參数以name=value&name1=value1的形式附到url的后面,假设是post请求,那么表单參数是在请求体中,也是以name=value& ...

  9. cocos2d-x快乐的做让人快乐的游戏3:cocos-2d 3.x中的物理世界

    Cocos2d-x 3.0+ 中全新的封装的物理引擎给了开发人员最大的便捷,你不用再繁琐与各种物理引擎的细节,全然的封装让开发人员能够更快更好的将物理引擎的机制加入�到自己的游戏中,简化的设计是从2. ...

  10. vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式

     vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式 #Region "WPF 当浏览器窗体关闭 ...