走入Integer的源码世界

int是个很常用的基本类型,Integer是int的包装类型,也是很常用的,那么我们就深入去了解一下Integer内部的原理吧。本来想的是从头到尾的阅读,发现并不靠谱,哈哈哈,对于自己来说,比较懵,还是从常用的方法入手吧。

1.首先看一下integer的最小值和最大值

    //看的出这个地方是JVM的本地方法,依赖于操作系统,一般来说是2的31次方的相反数
    @Native public static final int   MIN_VALUE = 0x80000000;
    //同上,2的31次方-1
    @Native public static final int   MAX_VALUE = 0x7fffffff;


2.integer对象的生成

Integer i1=129;
Integer i2=127;
Integer i3=new Integer(3);

这样就能够生成Integer的对象了,是不是和string有点类似啊,但是对象不是只能通过new、流、clone、反射的方式获得吗?

那么java的自动装箱是怎么样的喃?下面这段代码就是自动装箱的代码。

public static Integer valueOf(int i) {
        //读名字,也能够猜出IntegerCache是一个缓存区,是为了提高效率,节约空间的做法
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}

接下去看一下缓存

    private static class IntegerCache {
        static final int low = -128;//最小值
        static final int high;//最大值,在static中可以看出是127
        static final Integer cache[];//缓存数组

        static {
            // high value may be configured by property
            int h = 127;
            //这段代码是 代表,high的值可以配置的
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

那么就知道了,integer的对象是这样来的

(1)先判断是否在-128到127(最大值可以配置)之间

(2)如果在的话,就从缓存里面取出来,如果不在的话,就new一个对象

(3)如果是new对象的话,会给Integer内部的一个int赋值为i

3.toString()方法

    public String toString() {
        //value就是上面说的Integer的成员变量  等于i
        return toString(value);
    }
    public static String toString(int i) {
        //如果i等于最小值 就直接返回2的31次方的负数
        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);
    }
    //判断string的长度,例如1->1,10->2
    static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }
    static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;
        if (i < 0) {
            sign = '-';
            i = -i;
        }
        //当i>65536时,得到其后两位,从后往前放入数组里
        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;
        }
    }

4.valueOf(Strings s)方法

以前用valueOf(Strings s)和parseInt(Strings s)的时候并不能感觉到两者有什么差别,就是觉得差不多的,那么接下来就从源码的角度来看一下两者的区别。

public static Integer valueOf(String s) throws NumberFormatException {
          //接下来看一下parseInt(String,int)
          return Integer.valueOf(parseInt(s, 10));
}
public static int parseInt(String s, int radix) throws NumberFormatException{
        if (s == null) {
            throw new NumberFormatException("null");
        }
        //Character.MIN_RADIX=2  最少是2进制
        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }
        //Character.MIN_RADIX=36  最多是36进制
        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        int result = 0;
        //判断正负数
        boolean negative = false;
        int i = 0, len = s.length();
        int limit = -Integer.MAX_VALUE;
        int multmin;
        int digit;

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

                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;
    }
}
然后接着去valueOf(int)方法。

接下来看一parseInt(String)方法。

public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
}
后面的其实就是一样的了,所以,自己感觉得话会觉得parseInt如果不走缓存的话,那么效率可能会高一点。

5.hashCode()

public int hashCode() {
        return Integer.hashCode(value);
}
//也就是返回该值
public static int hashCode(int value) {
        return value;
}
6.equals()
public boolean equals(Object obj) {
        //先判断obj是不是integer
        if (obj instanceof Integer) {
             //对比值
             return value == ((Integer)obj).intValue();
        }
        return false;
}
public int intValue() {
        return value;
}

以后用到其他方法的时候再来拓展

猜你喜欢

转载自blog.csdn.net/qq_40384690/article/details/80719592