JDK25遇到的坑记录一下

在使用JDK21时

// 此代码对于time为16进制字符串时可以正常解析
long newTime = Long.parseLong(time) + skew;

在使用JDK25时

// 增加参数16才可以正常解析16进制str
long newTime = Long.parseLong(time,16) + skew;

对比底层实现

// JDK21 
// 底层实现逻辑更偏向于传统的,分步的命令式编程.
// 先处理符号,然后在一个循环中处理数字,每一步都进行清晰的边界检查

public static long parseLong(String s, int radix)
              throws NumberFormatException
    {
        if (s == null) {
            throw new NumberFormatException("Cannot parse null string");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }
        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        boolean negative = false;
        int i = 0, len = s.length();
        long limit = -Long.MAX_VALUE;

        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Long.MIN_VALUE;
                } else if (firstChar != '+') {
                    throw NumberFormatException.forInputString(s, radix);
                }

                if (len == 1) { // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s, radix);
                }
                i++;
            }
            long multmin = limit / radix;
            long result = 0;
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                int digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0 || result < multmin) {
                    throw NumberFormatException.forInputString(s, radix);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s, radix);
                }
                result -= digit;
            }
            return negative ? result : -result;
        } else {
            throw NumberFormatException.forInputString(s, radix);
        }
    }
// JDK25
// 底层实现逻辑更加紧凑和高度优化.
// 将多个条件判断合并到了一个复杂的 while 循环条件中,
// 并使用了一些位运算技巧(如 digit & 0xFF).
// 这通常是为了提升性能,减少分支预测失败,并让 JIT 编译器更容易进行优化

public static long parseLong(String s, int radix)
                throws NumberFormatException {
        if (s == null) {
            throw new NumberFormatException("Cannot parse null string");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException(String.format(
                "radix %s less than Character.MIN_RADIX", radix));
        }

        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException(String.format(
                "radix %s greater than Character.MAX_RADIX", radix));
        }

        int len = s.length();
        if (len == 0) {
            throw NumberFormatException.forInputString("", radix);
        }
        int digit = ~0xFF;
        int i = 0;
        char firstChar = s.charAt(i++);
        if (firstChar != '-' && firstChar != '+') {
            digit = digit(firstChar, radix);
        }
        if (digit >= 0 || digit == ~0xFF && len > 1) {
            long limit = firstChar != '-' ? MIN_VALUE + 1 : MIN_VALUE;
            long multmin = limit / radix;
            long result = -(digit & 0xFF);
            boolean inRange = true;
            /* Accumulating negatively avoids surprises near MAX_VALUE */
            while (i < len && (digit = digit(s.charAt(i++), radix)) >= 0
                    && (inRange = result > multmin
                        || result == multmin && digit <= (int) (radix * multmin - limit))) {
                result = radix * result - digit;
            }
            if (inRange && i == len && digit >= 0) {
                return firstChar != '-' ? -result : result;
            }
        }
        throw NumberFormatException.forInputString(s, radix);
    }