• Integer源码分析


    Integer中包含了大量的static方法。

    1.分析Integer的缓存机制:首先定义了一个缓存区,IntegerCache,其实就是一个Integer数组cache[],它默认存储了从-128~127这些Integer对象。

     1 private static class IntegerCache {
     2         static final int low = -128;
     3         static final int high;
     4         static final Integer cache[];
     5 
     6         static {
     7             // high value may be configured by property
     8             int h = 127;
     9             String integerCacheHighPropValue =
    10                 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    11             if (integerCacheHighPropValue != null) {
    12                 int i = parseInt(integerCacheHighPropValue);
    13                 i = Math.max(i, 127);
    14                 // Maximum array size is Integer.MAX_VALUE
    15                 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
    16             }
    17             high = h;
    18 
    19             cache = new Integer[(high - low) + 1];
    20             int j = low;
    21             for(int k = 0; k < cache.length; k++)
    22                 cache[k] = new Integer(j++);
    23         }
    24 
    25         private IntegerCache() {}
    26     }

    调用该内部类的代码是valueOf方法,

    在这里的assert IntegerCache.high >= 127 我认为是用于加载IntegerCache并执行static初始化代码段使用的(好像也不对,因为后面if语句中也可以初始化,???????请大神指正)。

    1 public static Integer valueOf(int i) {
    2         assert IntegerCache.high >= 127;
    3         if (i >= IntegerCache.low && i <= IntegerCache.high)
    4             return IntegerCache.cache[i + (-IntegerCache.low)];
    5         return new Integer(i);
    6     }

    2.getInteger方法用于获取对应系统字符串代表的整形数,如果想要直接获取字符串代表的整形数,使用decode()方法,如decode(“123”) ----> 123

     1 public static Integer getInteger(String nm) {
     2         return getInteger(nm, null);
     3     }
     4 
     5 public static Integer getInteger(String nm, int val) {
     6         Integer result = getInteger(nm, null);
     7         return (result == null) ? Integer.valueOf(val) : result;
     8     }
     9 
    10 public static Integer getInteger(String nm, Integer val) {
    11         String v = null;
    12         try {
    13             v = System.getProperty(nm);
    14         } catch (IllegalArgumentException e) {
    15         } catch (NullPointerException e) {
    16         }
    17         if (v != null) {
    18             try {
    19                 return Integer.decode(v);
    20             } catch (NumberFormatException e) {
    21             }
    22         }
    23         return val;
    24     }

      getInteger方法最终调用decode方法返回整数,decode方法如下:其实最终调用的还是方法parseInt,这里只是将字符串的前缀判断一下,数字的部分用parseInt方法获取结果

     1 public static Integer decode(String nm) throws NumberFormatException {
     2         int radix = 10;
     3         int index = 0;
     4         boolean negative = false;
     5         Integer result;
     6 
     7         if (nm.length() == 0)
     8             throw new NumberFormatException("Zero length string");
     9         char firstChar = nm.charAt(0);
    10         // Handle sign, if present
    11         if (firstChar == '-') {
    12             negative = true;
    13             index++;
    14         } else if (firstChar == '+')
    15             index++;
    16 
    17         // Handle radix specifier, if present
    18         if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
    19             index += 2;
    20             radix = 16;
    21         }
    22         else if (nm.startsWith("#", index)) {
    23             index ++;
    24             radix = 16;
    25         }
    26         else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
    27             index ++;
    28             radix = 8;
    29         }
    30 
    31         if (nm.startsWith("-", index) || nm.startsWith("+", index))
    32             throw new NumberFormatException("Sign character in wrong position");
    33 
    34         try {
    35             result = Integer.valueOf(nm.substring(index), radix);
    36             result = negative ? Integer.valueOf(-result.intValue()) : result;
    37         } catch (NumberFormatException e) {
    38             // If number is Integer.MIN_VALUE, we'll end up here. The next line
    39             // handles this case, and causes any genuine format error to be
    40             // rethrown.
    41             String constant = negative ? ("-" + nm.substring(index))
    42                                        : nm.substring(index);
    43             result = Integer.valueOf(constant, radix);
    44         }
    45         return result;
    46     }

    3.parseInt方法,该方法将为纯数字的字符串以规定的进制radix(2~36,查看Character类可得到)转为相应的int数字

     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 
    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         boolean negative = false;
    26         int i = 0, len = s.length();
    27         int limit = -Integer.MAX_VALUE;
    28         int multmin;
    29         int digit;
    30 
    31         if (len > 0) {
    32             char firstChar = s.charAt(0);
    33             if (firstChar < '0') { // Possible leading "+" or "-"
    34                 if (firstChar == '-') {
    35                     negative = true;
    36                     limit = Integer.MIN_VALUE;
    37                 } else if (firstChar != '+')
    38                     throw NumberFormatException.forInputString(s);
    39 
    40                 if (len == 1) // Cannot have lone "+" or "-"
    41                     throw NumberFormatException.forInputString(s);
    42                 i++;
    43             }
    44             multmin = limit / radix;
    45             while (i < len) {
    46                 // Accumulating negatively avoids surprises near MAX_VALUE
    47                 digit = Character.digit(s.charAt(i++),radix);
    48                 if (digit < 0) {
    49                     throw NumberFormatException.forInputString(s);
    50                 }
    51                 if (result < multmin) {
    52                     throw NumberFormatException.forInputString(s);
    53                 }
    54                 result *= radix;
    55                 if (result < limit + digit) {
    56                     throw NumberFormatException.forInputString(s);
    57                 }
    58                 result -= digit;
    59             }
    60         } else {
    61             throw NumberFormatException.forInputString(s);
    62         }
    63         return negative ? result : -result;
    64     }
    65 
    66 public static int parseInt(String s) throws NumberFormatException {
    67         return parseInt(s,10);
    68     }

    4.静态的toString方法:源代码的实现方式比较奇怪,先贴在这里:

    //一个代表整形的串中可能出现的字符 所组成的数组
    final static char[] digits = {
            '0' , '1' , '2' , '3' , '4' , '5' ,
            '6' , '7' , '8' , '9' , 'a' , 'b' ,
            'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
            'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
            'o' , 'p' , 'q' , 'r' , 's' , 't' ,
            'u' , 'v' , 'w' , 'x' , 'y' , 'z'
        };
    
    //将整形以对应的基数radix转为字符串
    public static String toString(int i, int radix) {
    
            if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
                radix = 10;
    
            /* Use the faster version */
            if (radix == 10) {
                return toString(i);
            }
    
            char buf[] = new char[33];
            boolean negative = (i < 0);
            int charPos = 32;
    
            if (!negative) {
                i = -i;
            }
    
            while (i <= -radix) {
                buf[charPos--] = digits[-(i % radix)];
                i = i / radix;
            }
            buf[charPos] = digits[-i];
    
            if (negative) {
                buf[--charPos] = '-';
            }
    
            return new String(buf, charPos, (33 - charPos));
        }
    
    
    public static String toHexString(int i) {
            return toUnsignedString(i, 4);
        }
    
    public static String toOctalString(int i) {
            return toUnsignedString(i, 3);
        }
    
    public static String toBinaryString(int i) {
            return toUnsignedString(i, 1);
        }
    
    //shift表示将基数左移的位数,然后
     private static String toUnsignedString(int i, int shift) {
            char[] buf = new char[32];
            int charPos = 32;
            int radix = 1 << shift;
            int mask = radix - 1;
            do {
                buf[--charPos] = digits[i & mask];
                i >>>= shift;
            } while (i != 0);
    
            return new String(buf, charPos, (32 - charPos));
        }
    
     final static char [] DigitTens = {
            '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
            '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
            '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
            '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
            '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
            '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
            '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
            '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
            '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
            '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
            } ;
    
        final static char [] DigitOnes = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            } ;
    
    public static String toString(int i) {
            if (i == Integer.MIN_VALUE)
                return "-2147483648";
            int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
            char[] buf = new char[size];
            getChars(i, size, buf);
            return new String(buf, true);
        }
    
    static void getChars(int i, int index, char[] buf) {
            int q, r;
            int charPos = index;
            char sign = 0;
    
            if (i < 0) {
                sign = '-';
                i = -i;
            }
    
            // Generate two digits per iteration
            while (i >= 65536) {
                q = i / 100;
            // really: r = i - (q * 100);
                r = i - ((q << 6) + (q << 5) + (q << 2));
                i = q;
                buf [--charPos] = DigitOnes[r];
                buf [--charPos] = DigitTens[r];
            }
    
            // Fall thru to fast mode for smaller numbers
            // assert(i <= 65536, i);
            for (;;) {
                q = (i * 52429) >>> (16+3);
                r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
                buf [--charPos] = digits [r];
                i = q;
                if (i == 0) break;
            }
            if (sign != 0) {
                buf [--charPos] = sign;
            }
        }
    
        final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                          99999999, 999999999, Integer.MAX_VALUE };
    
        // Requires positive x
        static int stringSize(int x) {
            for (int i=0; ; i++)
                if (x <= sizeTable[i])
                    return i+1;
        }

    后续可以参考:http://www.cnblogs.com/hanmou/p/3463984.html

  • 相关阅读:
    sublime Text3 常用插件
    No input file specified. nginx服务器报错解决
    has~和belongsTo的区别?
    关于在phpStudy环境下,windows cmd中 php不是内部命令问题
    spring @RequestMapping注解技巧
    VIM快捷键
    Thinkphp5 模块的自动生成
    在php中define和const定义常量的区别
    go语言学习(六)——并发编程
    go语言学习(五)——面向对象编程
  • 原文地址:https://www.cnblogs.com/ljdblog/p/5971143.html
Copyright © 2020-2023  润新知