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

时间: 2024-09-08 08:08:30

StringUtils.isNumeric(String str) 的一个坑(转)的相关文章

为什么vector的string类型的一个空间只能存放12个元素,怎么加大?

问题描述 为什么vector的string类型的一个空间只能存放12个元素,怎么加大? 解决方案 解决方案二: 求路过的大神帮帮忙,明天交作业啦! 解决方案三: 不是的,当你放入更多的字符串,它会自动延展的. 解决方案四: vector是动态数组类型,当空间满了,你再次插入数据,他就会自动扩展空间,比如2倍.

MySQL JDBC的queryTimeout的一个坑

遇到一个MySQL JDBC执行execute方法时指定queryTimeout的坑,比较恶心,算是它的BUG,也可以不算,^_^,为啥这么说?看一下下面的解释: 现象: 用同一个Connection执行大批量SQL的时候,导致了OOM现象. 细节现象描述: 1.SQL是从某个存储设备上拿到的,不会直接占用大量的内存,每次只会取最多1千条数据过去,也会判定容量不超过多少M. 2.每一批SQL执行会单独创建Statement对象,执行一批SQL后,会将这个Statement关闭掉. 3.SQL语句

string这是一个指向char型的指针,能把一个字符串赋给它吗

问题描述 string这是一个指向char型的指针,能把一个字符串赋给它吗 解决方案 char *String = "I Love A"; //表示String指向常量字符串"I Love A"的首地址,即String的内容是字符串的首地址 解决方案二: 你那样写有问题的,你申明string为字符指针,string是一个指针,赋值只能是指针类型的值,但是你赋值的是一个字符串 解决方案三: "I love xxx"表示的就是这个字符串的指针,所以赋

罗永浩:每一个情怀都是一个坑

摘要: 今天下午两点半,罗永浩在北京发布了可能是最后一期一个理想主义者的创业故事的主题演讲,反思了自己进入手机市场之后的的创业经历.在发布会上,罗永浩把锤子科技两年来遇到 今天下午两点半,罗永浩在北京发布了可能是最后一期"一个理想主义者的创业故事"的主题演讲,反思了自己进入手机市场之后的的创业经历.在发布会上,罗永浩把"锤子科技"两年来遇到的为题归因于两点:供应链生产和与媒体关系. 每一个情怀都是一个坑 罗永浩回顾过去半年锤子手机Smartisan T1生产中遇到的

java-关于String[]数组的一个小问题

问题描述 关于String[]数组的一个小问题 1.String[] y = x.toArray(new String[0]); 2.String[] y = new String[0]; y = x.toArray(y); 这两个有什么区别呢?实际效果一样吗?相比而言,哪个更优呢?谢谢! 解决方案 两个区别不大,如果考虑性能,第二种效果比较差. 如果x为一个长度为5的ArrayList. (1)String[] y = new String[0]; 声明了一个变量,y指向一个长度为1的字符数组

关于String中的一个递归问题

问题描述 关于String中的一个递归问题 今天学习java String时,遇到书上讲的一个递归问题,先上代码 import java.util.*; public class InfiniteRecursion { public String toStirng() { return "InfiniteRecursion address: "+ this +"n"; } public static void main(String[] args) { List&l

stringbuilder-太没有道理了,g++编译这么简单的程序出现错误:‘string’不是一个类型名

问题描述 太没有道理了,g++编译这么简单的程序出现错误:'string'不是一个类型名 using namespace std;#include templateclass tree_node_t{public: string &to_string(string *result int prefix = 0); void set_data(const T &data); protected: T m_data;}; vs编译得好好的,g++怎么了,老是这些莫名其妙的错误?哪位高手能看出端

c#-C# 如何表示出 string [] str 数组的个数

问题描述 C# 如何表示出 string [] str 数组的个数 数组 string [] str, 如何表示数组str的个数 解决方案 str.length 解决方案二: 这么简单的问题,为啥我就没见过呢-- str.Length str.Count() 解决方案三: str.length

Javascript之旅——第八站:说说instanceof踩了一个坑

原文:Javascript之旅--第八站:说说instanceof踩了一个坑 前些天写js遇到了一个instanceof的坑,我们的页面中有一个iframe,我在index页面中计算得到了一个array,然后需要传递到Flight页面 这个嵌套的iframe中的一个函数(SearchFlight)中,作为防御性编程,我需要在SearchFlight函数中进行参数检测,也就是判断过来的参数一 定是Array类型.   一:抛出问题 举个例子,下面有两个页面. Index.html页面 1 <!DO