在项目中遇到一处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 数字。

肯爹的 StringUtils.isNumeric(String str)的更多相关文章

  1. StringUtils.isNumeric(String str) 的一个坑(转)

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

  2. StringUtils.isNumeric()的特殊点

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

  3. StringUtils.isNumeric使用

    在做导入/导出功能时,客户要求导出数字类型的值时,将excel相应单元格属性设为number型,由此需判断字符串值是否为数字,代码如下: public static boolean isNumber( ...

  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. Asp.net中使用Server.HtmlDecode(string str)的使用

    前言: 在使用Visual Studio开发web页面时,需要在GridView中绑定Table数据,并加入了CommandField, 试图,点击详情按钮是,获取GridView中Rows中Cell ...

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

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

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

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

  9. String str 与 String str=new String("") 区别

    1.当使用String str="abc",这种方式时,先去内存的Heap中找是否存在"abc"这个字符串,若存在,则将地址引用.若不存在则创建. 2.当使用S ...

随机推荐

  1. IOS开发UI基础之UIButton

    什么是按钮?

  2. BZOJ1008 /乘法原理+快速幂 解题报告

    1008: [HNOI2008]越狱 Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生 ...

  3. UnityShader快速上手指南(四)

    简介 由于其他项目中断了几天更新,继续~~ 这一篇主要是讲光照的(包含漫反射和高光以及多光源的处理) 还是先来看看具体效果(多光源后面单独展示) 有了基本的光照处理之后越来越有立体感了有不有 ╮(╯▽ ...

  4. Python入门笔记(13):列表解析

    一.列表解析 列表解析来自函数式编程语言(haskell),语法如下: [expr for iter_var in iterable] [expr for iter_var in iterable i ...

  5. 重新想象 Windows 8.1 Store Apps (82) - 绑定: DataContextChanged, TargetNullValue, FallbackValue, UpdateSourceTrigger

    [源码下载] 重新想象 Windows 8.1 Store Apps (82) - 绑定: DataContextChanged, TargetNullValue, FallbackValue, Up ...

  6. fibonacci数列的和取余(2)

    Maybe ACMers of HIT are always fond of fibonacci numbers, because it is so beautiful. Don't you thin ...

  7. 【JVM】2、关于jdk7的MethodHandle类

    关于MethodHandle类,这个类是在jdk1.7之后加入的,这个类的作用类似函数指针的意思 这个类中有一个方法 这里我的jdk有一个问题,就是我在进行MethodHandle操作的时候,我们会发 ...

  8. linux环形buff模拟多线程信号量操作

    互斥锁mutex变量的值非0即1,只能用来表示两种状态下的临界资源.而信号量是与之类似的,用来表示可用资源的,区别在于,信号量可以表示多个可用资源的. --值为2的信号量也就是特殊的互斥锁了. 那么下 ...

  9. JS基本概念 -- 数据类型(一)

    ECMAScript中有5种简单数据类型(也成为基本数据类型): Undefined.Null.Boolean.Number.String; 1种复杂数据类型: Object,Object本质上是由一 ...

  10. 链接错误——无法解析的外部符号 ConvertStringToBST

    今天做COM组件时,编译之后,出现了一个数个编译错误:error LNK2019: 无法解析的外部符号 "wchar_t * __stdcall _com_util::ConvertStri ...