肯爹的 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 數字。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM