zoukankan      html  css  js  c++  java
  • Integer.parseInt不同jdk源码解析

    执行以下代码:

    System.out.println(Integer.parseInt("-123"));
    System.out.println(Integer.parseInt("+123"));
    

     以上提供1.6、1.7和1.8三个版本的比较

     1.6版本执行结果为:

     

     1.7版本执行结果为:

     1.8版本执行结果为:

    从两方面去查证结果的原因,分别是:查看API文档 和 查看对应的源代码

    【查看API文档】

     1.6版本对应的API文档:

     

     1.7版本对应的API文档:

     

     1.8版本对应的API文档:

     可以看出,对第一个首字符,1.6只对 '-' 做了判定;1.7和1.8对 '-' 和 '+' 都做了判定。

    【查看JDK源码】

     1.6版本对应的源代码:

     1 char firstChar = s.charAt(0);
     2 if (firstChar < '0') { // Possible leading "+" or "-"
     3     if (firstChar == '-') {
     4         negative = true;
     5         limit = Integer.MIN_VALUE;
     6     }
     7 
     8     if (len == 1) // Cannot have lone "+" or "-"
     9         throw NumberFormatException.forInputString(s);
    10     i++;
    11 }

      1.7版本对应的源代码:

     1 char firstChar = s.charAt(0);
     2 if (firstChar < '0') { // Possible leading "+" or "-"
     3     if (firstChar == '-') {
     4         negative = true;
     5         limit = Integer.MIN_VALUE;
     6     } else if (firstChar != '+')
     7         throw NumberFormatException.forInputString(s);
     8 
     9     if (len == 1) // Cannot have lone "+" or "-"
    10         throw NumberFormatException.forInputString(s);
    11     i++;
    12 }

     1.8的和1.7的源代码一样,这里就不冗余贴出来了。

     对应jdk1.8源代码并做了相应的注解源码如下所示,帮助大家一起更加深入的理解:

     1 public static int parseInt(String s, int radix) throws NumberFormatException {
     2     /*
     3      * WARNING: This method may be invoked early during VM initialization
     4      * before IntegerCache is initialized. Care must be taken to not use
     5      * the valueOf method.
     6      */
     7     // 下面三个判断好理解,其中表示进制的 radix 要在(2~36)范围内  
     8     if (s == null) {
     9         throw new NumberFormatException("null");
    10     }
    11 
    12     if (radix < Character.MIN_RADIX) {
    13         throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
    14     }
    15 
    16     if (radix > Character.MAX_RADIX) {
    17         throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
    18     }
    19 
    20     /**
    21     * 表示结果, 在下面的计算中会一直是个负数
    22     * 假如说 我们的字符串是一个正数  "7",那么在返回这个值之前result保存的是 -7
    23     * 这个可能是为了保持正数和负数在下面计算的一致性
    24     */
    25     int result = 0;
    26     boolean negative = false;
    27     int i = 0, len = s.length();
    28 
    29     /**
    30     * limit 默认初始化为 最大正整数的 负数 ,假如字符串表示的是正数
    31     * 那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较,判断是否溢出
    32     */
    33     int limit = -Integer.MAX_VALUE;
    34     int multmin;
    35     int digit;
    36 
    37     if (len > 0) {
    38         char firstChar = s.charAt(0); //首先是对第一个位置判断,是否含有正负号  
    39         if (firstChar < '0') { // Possible leading "+" or "-"
    40             if (firstChar == '-') {
    41                 negative = true;
    42                 //这里在负号的情况下,判断溢出的值就变成了 整数的 最小负数了
    43                 limit = Integer.MIN_VALUE;
    44             } else if (firstChar != '+')
    45                 throw NumberFormatException.forInputString(s);
    46 
    47             if (len == 1) // Cannot have lone "+" or "-"
    48                 throw NumberFormatException.forInputString(s);
    49             i++;
    50         }
    51         multmin = limit / radix;
    52         /**
    53         * len为输入字符串的长度,i为循环len自增变量
    54         * result初始值为0,multmin初始值为最大负整数/进制数
    55         */
    56         while (i < len) {
    57             // Accumulating negatively avoids surprises near MAX_VALUE
    58             //根据Character类获取当前对应字符对应进制的数字
    59             digit = Character.digit(s.charAt(i++),radix);
    60             if (digit < 0) {
    61                 throw NumberFormatException.forInputString(s);
    62             }
    63 
    64             /**
    65             * 这里就是上面说的判断溢出,由于result统一用负值来计算,所以用了 小于 号
    66             */
    67             if (result < multmin) {
    68                 throw NumberFormatException.forInputString(s);
    69             }
    70             result *= radix;
    71             if (result < limit + digit) {
    72                 throw NumberFormatException.forInputString(s);
    73             }
    74             result -= digit;
    75             /**
    76             * 再来个假设:一开始输入一个数字字符串为123,那么对应的radix=10(因为是10进制的),digit = 123 / 10 计算得到的
    77             * 第一次result *= radix --> result = 0 ;  result -= digit --> result = -1
    78             * 第二次result *= radix --> result = -10; result -= digit --> result = -12
    79             * 第三次result *= radix --> result = -12; result -= digit --> result = -123
    80             * 此时,negative = false,则返回 -result,即最终结果为:123
    81             */
    82         }
    83     } else {
    84         throw NumberFormatException.forInputString(s);
    85     }
    86     return negative ? result : -result;
    87 }

      从以上源码可以看出,作者在计算整型数字的时候是采用取反的操作,即正数是通过负数进行计算,返回再取反操作。我猜想这样是为了在计算正负数的时候采取相同的策略,不需要为正数写一套方案,负数写一套方案,可以避免重复代码的嫌疑。

  • 相关阅读:
    winform 剔除空格与换行显示
    编码
    todo
    react高阶函数组件
    Docker-compose Setup for Self-hosting Development & Deployment Tools
    Self-hosting Sentry With Docker and Docker-compose
    how does Array.prototype.slice.call() work?
    todo reading
    a better git log
    https://coderwall.com/p/7smjkq/multiple-ssh-keys-for-different-accounts-on-github-or-gitlab
  • 原文地址:https://www.cnblogs.com/liang1101/p/6380313.html
Copyright © 2011-2022 走看看