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

posted @ 2016-10-17 20:34  博学善思。。ljd  阅读(573)  评论(0编辑  收藏  举报