首页 > 代码库 > 肯爹的 StringUtils.isNumeric(String str)

肯爹的 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 nullReturns:true if only contains digits, and is non-null

只能包含 unicode 的数字, +, -, . 三者都不能算作是unicode 数字。

 

肯爹的 StringUtils.isNumeric(String str)