Java Integer类源码分析

最近研究了一下Integer类,记录一下

概述

Integer是int基础数据类型的包装类,实际值是Integer的属性value ,继承自 Number类, 最大值 0x7fffffff ,最小值:0x80000000
Integer 有个内部缓存类IntegerCache默认缓存 -128 ~ 127
当使用Integer.value(i) 时,优先取cache中的值;

	Integer a = new Integer(1);
        Integer b = new Integer(1);
        Integer c = 1;
        Integer d = 1;
        Integer e = 128;
        Integer f = 128;
        System.out.println(a == b);
        System.out.println(c == d);
        System.out.println(e == f);

运行结果:

false
true
false
常用方法
hashCode()

返回就是Integer本身的值

    @Override
    public int hashCode() {
        return Integer.hashCode(value);
    }
    public static int hashCode(int value) {
        return value;
    }
Integer.parserInt(String s, int radix) 字符串转不同进制的int

radix范围: 2<=radix<=36
代码:

public static int parseInt(String s, int radix) throws NumberFormatException {
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */

        if (s == null) {
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }

        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) {
            // 1
            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++;
            }
            // 2
            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);
        }
        // 3
        return negative ? result : -result;
    }

1、首字符判断数字正负数,确定数值范围
2、从最高位开始,取值转换成数字,累计最终值,注意这里是做减法运算
因为负数比正数多1位。

result *= radix;
result -= digit;
Integer.toString(int i) 数字转字符串

parseInt的反向操作,这里是转成10进制数字的字符串
代码:

    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);
    }

1、如果是最小值,直接返回,简化计算
2、计算总字符串长度,负数+1位
3、利用字符数组存入每一位字符
4、返回字符串
再看getChars(i, size, buf)代码:

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;
        }
    }

这里 ,
①r = i - ((q << 6) + (q << 5) + (q << 2)); 相当于 r = i - (q100), 乘法运算的实现其实也是位移,这里直接使用位移速度更快;
②当i<65536时,q = (i * 52429) >>> (16+3);这段代码其实就是q=i/10 ,其中 (double)52429/(1<<19)=0.10000038146972656也就是在int型的时候计算一个数的十分之1的精度是够的;
③r = i - ((q << 3) + (q << 1)); 这里没有使用i%10,而是 i - (q
10)
当i>=65536时,一次性取两个字符,优化了速度

stringSize(int x)

获取数字的长度,这里使用了一个数组,数组里面放了int每位数上的最大值

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;
    }

参考链接:
https://www.cnblogs.com/lxcmyf/p/6427972.html

Java 自动装箱(Autoboxing)是 Java 1.5 版本之后引入的新特性,可以将基本型自动转换为对应的包装型,反之也可以。具体来说,就是在需要使用包装型的地方,可以直接使用基本型,而 Java 编译器会自动将其转换为对应的包装型。 Java 自动装箱的实现是通过编译器在编译期间自动插入装箱(Boxing)和拆箱(Unboxing)的代码来完成的。具体来说,当编译器发现一个需要使用包装型的地方,它会自动插入一个将基本型转换为包装型的代码,而当编译器发现一个需要使用基本型的地方,它会自动插入一个将包装型转换为基本型的代码。 下面简单介绍一下自动装箱的源码实现: 1. 自动装箱 自动装箱是通过调用对应包装型的 valueOf 方法来实现的。例如,当需要将 int 型的变量 i 转换为 Integer 型时,编译器会自动插入如下代码: ```java Integer i = Integer.valueOf(i); ``` 其中,valueOf 方法定义在对应包装型的中,例如 Integer 中的 valueOf 方法如下: ```java public static Integer valueOf(int i) { return new Integer(i); } ``` 2. 自动拆箱 自动拆箱是通过调用对应包装型的 xxxValue 方法来实现的。例如,当需要将 Integer 型的变量 i 转换为 int 型时,编译器会自动插入如下代码: ```java int i = i.intValue(); ``` 其中,xxxValue 方法定义在对应包装型的中,例如 Integer 中的 intValue 方法如下: ```java public int intValue() { return value; } ``` 以上是 Java 自动装箱的源码分析,希望对你有所帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值