• 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

  • 相关阅读:
    STM32之系统滴答定时器
    MPU6050带字符驱动的i2c从设备驱动2
    MPU6050带字符驱动的i2c从设备驱动1
    基于μC/OS—III的CC1120驱动程序设计
    STM32串口DMA超时接收方法,可大大节约CPU时间
    neo1973 audio subsystem
    题解模板
    在 GoLang 中使用 jwt 进行认证
    (OperationNotSupportedInTransaction) Cannot create namespace test.application in multi-document transaction 错误的解决方法
    server selection timeout, current topology: { Type: ReplicaSetNoPrimary, Servers: Type: RSGhost 错误的解决方法
  • 原文地址:https://www.cnblogs.com/softidea/p/4527593.html
Copyright © 2020-2023  润新知