StringUtils.isNumeric(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; 
    <span style="color:#0000ff;">if (codePoint &gt;= MIN_CODE_POINT &amp;&amp; codePoint &lt;=<span style="color:#000000;"> FAST_PATH_MAX) {
        bDigit =<span style="color:#000000;"> CharacterDataLatin1.isDigit(codePoint);
    } <span style="color:#0000ff;">else<span style="color:#000000;"> {
        <span style="color:#0000ff;">int plane =<span style="color:#000000;"> getPlane(codePoint);
        <span style="color:#0000ff;">switch<span style="color:#000000;">(plane) {
        <span style="color:#0000ff;">case(0<span style="color:#000000;">):
            bDigit =<span style="color:#000000;"> CharacterData00.isDigit(codePoint);
            <span style="color:#0000ff;">break<span style="color:#000000;">;
        <span style="color:#0000ff;">case(1<span style="color:#000000;">):
            bDigit =<span style="color:#000000;"> CharacterData01.isDigit(codePoint);
            <span style="color:#0000ff;">break<span style="color:#000000;">;
        <span style="color:#0000ff;">case(2<span style="color:#000000;">):
            bDigit =<span style="color:#000000;"> CharacterData02.isDigit(codePoint);
            <span style="color:#0000ff;">break<span style="color:#000000;">;
        <span style="color:#0000ff;">case(3): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(4): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(5): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(6): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(7): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(8): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(9): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(10): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(11): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(12): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
        <span style="color:#0000ff;">case(13): <span style="color:#008000;">//<span style="color:#008000;"> Undefined
            bDigit =<span style="color:#000000;"> CharacterDataUndefined.isDigit(codePoint);
            <span style="color:#0000ff;">break<span style="color:#000000;">;
        <span style="color:#0000ff;">case(14<span style="color:#000000;">):
            bDigit =<span style="color:#000000;"> CharacterData0E.isDigit(codePoint);
            <span style="color:#0000ff;">break<span style="color:#000000;">;
        <span style="color:#0000ff;">case(15): <span style="color:#008000;">//<span style="color:#008000;"> Private Use
        <span style="color:#0000ff;">case(16): <span style="color:#008000;">//<span style="color:#008000;"> Private Use
            bDigit =<span style="color:#000000;"> CharacterDataPrivateUse.isDigit(codePoint);
            <span style="color:#0000ff;">break<span style="color:#000000;">;
        <span style="color:#0000ff;">default<span style="color:#000000;">:
            <span style="color:#008000;">//<span style="color:#008000;"> the argument's plane is invalid, and thus is an invalid codepoint
            <span style="color:#008000;">//<span style="color:#008000;"> bDigit remains false;
            <span style="color:#0000ff;">break<span style="color:#000000;">;                          
        }
    }
    <span style="color:#0000ff;">return<span style="color:#000000;"> bDigit;
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
复制代码

在下面一步失败:

 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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值