JDK 1.7 Integer.parseInt 源码解析

  1. public static int parseInt(String s, int radix)  
  2.                 throws NumberFormatException  
  3.     {  
  4.         /* 
  5.          * WARNING: This method may be invoked early during VM initialization 
  6.          * before IntegerCache is initialized. Care must be taken to not use 
  7.          * the valueOf method. 
  8.          */  
  9.     // 下面三个判断好理解,其中表示进制的 radix 要在(2~36)范围内  
  10.         if (s == null) {  
  11.             throw new NumberFormatException("null");  
  12.         }  
  13.   
  14.         if (radix < Character.MIN_RADIX) {  
  15.             throw new NumberFormatException("radix " + radix +  
  16.                                             " less than Character.MIN_RADIX");  
  17.         }  
  18.   
  19.         if (radix > Character.MAX_RADIX) {  
  20.             throw new NumberFormatException("radix " + radix +  
  21.                                             " greater than Character.MAX_RADIX");  
  22.         }  
  23.   
  24.         int result = 0// 表示结果, 在下面的计算中会一直是个负数,   
  25.             // 假如说 我们的字符串是一个正数  "7" ,   
  26.             // 那么在返回这个值之前result保存的是 -7,  
  27.             // 这个可能是为了保持正数和负数在下面计算的一致性  
  28.         boolean negative = false;  
  29.         int i = 0, len = s.length();  
  30.   
  31.   
  32.     //limit 默认初始化为 最大正整数的  负数 ,假如字符串表示的是正数,  
  33.     //那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较,判断是否溢出  
  34.   
  35.         int limit = -Integer.MAX_VALUE;   
  36.               
  37.         int multmin;  
  38.         int digit;  
  39.   
  40.         if (len > 0) {     // 首先是对第一个位置判断,是否含有正负号  
  41.             char firstChar = s.charAt(0);  
  42.             if (firstChar < '0') { // Possible leading "+" or "-"  
  43.                 if (firstChar == '-') {  
  44.                     negative = true;  
  45.               
  46.             // 这里,在负号的情况下,判断溢出的值就变成了 整数的 最小负数了。  
  47.                     limit = Integer.MIN_VALUE;  
  48.   
  49.                 } else if (firstChar != '+')  
  50.                     throw NumberFormatException.forInputString(s);  
  51.   
  52.                 if (len == 1// Cannot have lone "+" or "-"  
  53.                     throw NumberFormatException.forInputString(s);  
  54.                 i++;  
  55.             }  
  56.   
  57.             multmin = limit / radix;  
  58.         // 这个是用来判断当前的 result 在接受下一个字符串位置的数字后会不会溢出。  
  59.         //  原理很简单,为了方便,拿正数来说  
  60.         //  (multmin result 在计算中都是负数),假如是10  
  61.         // 进制,假设最大的10进制数是 21,那么multmin = 21/10 = 2,   
  62.         //  如果我此时的 result 是 3 ,下一个字符c来了,result即将变成  
  63.         // result = result * 10 + c;那么这个值是肯定大于 21 ,即溢出了,  
  64.             //  这个溢出的值在 int里面是保存不了的,不可能先计算出  
  65.         // result(此时的result已经不是溢出的那个值了) 后再去与最大值比较。    
  66.         // 所以要通过先比较  result < multmin   (说明result * radix 后还比 limit 小)     
  67.   
  68.             while (i < len) {  
  69.                 // Accumulating negatively avoids surprises near MAX_VALUE  
  70.                 digit = Character.digit(s.charAt(i++),radix);  
  71.                 if (digit < 0) {  
  72.                     throw NumberFormatException.forInputString(s);  
  73.                 }  
  74.   
  75.   
  76.         // 这里就是上说的判断溢出,由于result统一用负值来计算,所以用了 小于 号  
  77.         // 从正数的角度看就是   reslut > mulmin  下一步reslut * radix 肯定是 溢出了  
  78.                 if (result < multmin) {   
  79.                     throw NumberFormatException.forInputString(s);  
  80.                 }  
  81.   
  82.   
  83.   
  84.                 result *= radix;  
  85.   
  86.         // 这里也是判断溢出, 由于是负值来判断,相当于 (-result + digit)> - limit  
  87.         // 但是不能用这种形式,如果这样去比较,那么得出的值是肯定判断不出溢出的。  
  88.         // 所以用    result < limit + digit    很巧妙  
  89.                 if (result < limit + digit) {  
  90.   
  91.                     throw NumberFormatException.forInputString(s);  
  92.                 }  
  93.                 result -= digit; // 加上这个 digit 的值 (这里减就相当于加)  
  94.             }  
  95.         } else {  
  96.             throw NumberFormatException.forInputString(s);  
  97.         }  
  98.         return negative ? result : -result; // 正数就返回  -result   
  99.     }  


   注  :转换成负数来计算的主要原因是防止溢出,
8位的正负数范围是 -128 ~ 127 所以,正数转换成负数不会溢出,最小负数转换成正数会溢出


你可能感兴趣的:(JDK 1.7 Integer.parseInt 源码解析)