java源码分析(1)-Integer

Integer源码分析:

1.Integer的取值范围

    Integer中定义的范围为 MIN_VALUE = 0x80000000,MAX_VALUE = 0x7fffffff,大约为-21亿~ +21亿。

2.toString方法

        Integer的toString方法有3个,

         1.toString()

                该方法默认调用toString(int i),并将自己的值作为参数。

         2.toString(int i)//只能处理十进制的Integer           
        

 public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";//必须这样处理最小值,因为下面的getChars(i, size, buf)会把负数转化成正数
            来取每一位数字,Integer最小值的绝对值比最大值大1,会越界,顾需要单独处理    
       int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);//取Integer的位数,负数因为有负号,要加1,
                                                                stringSize()见下面
        char[] buf = new char[size];
        getChars(i, size, buf);//取每一位的数字,详情见下面
        return new String(buf, true);
    }
    final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
   99999999, 999999999, Integer.MAX_VALUE };
   static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])//与sizeTable比较,确定Integer的位数                                            
                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;//将负数转化为正数处理,提高效率
        }
        while (i >= 65536) {//将值判断大小后取每个数字,较大的数字一次取两位(大数字运算消耗大),
                     变为小数字后使用下面小数字的方法取每一位数字,性能更好,效率更高
            q = i / 100;
            r = i - ((q << 6) + (q << 5) + (q << 2));//此处使用了位运算(2*6+2*5+2*2=100),
                     位运算的效率高于乘法,此处结果为一个两位数(个位和十位)
            i = q;//重新赋值,准备下一次循环
            buf [--charPos] = DigitOnes[r];//取个位的数字,默认数组请看下面
            buf [--charPos] = DigitTens[r];//取十位数字
        }
        for (;;) {//小数字运算消耗较小,故一次只取一位较划算
            q = (i * 52429) >>> (16+3);//52429/(2*19)约等于1,此处这样设计是为了提高精度
            r = i - ((q << 3) + (q << 1));//即r=i-10q,此处采用位运算,相较于乘法消耗较小
            buf [--charPos] = digits [r];//取最后一位的数字
            i = q;//重新赋值,准备下一次循环
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }
       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',
        } ;
      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'
    };

         3.toString(int i,int radix)//处理各种进制的Integer

public static String toString(int i, int radix) {

        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;//即当传入的进制数小于2或大约36时,默认为10,而不是报错

        /* Use the faster version */
        if (radix == 10) {
            return toString(i);
        }

        char buf[] = new char[33];//2*32约为41亿,才能放下21亿的Integer值,加上一位正负号,为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] = '-';//为负数在buf[0]加上负号
        }

        return new String(buf, charPos, (33 - charPos));
    }
3.Integer.hashcode()
         Integer的hashcode就是其本身的值(value),未做任何处理。

4.static class IntegerCache

       该类缓存了-128~127的值,在jvm启动时便创建,当程序中直接使用这些值时,边不需创建,直接可以使用这里的值,故此会发生以下的事情

public static void main(String[] args) {
		Integer a=5;
		Integer b=5;
		Integer c=new Integer(5);
		Integer d=128;
		Integer e=128;
		Integer f=new Integer(128);
		System.out.println(a==b);//true,取的是缓存中的Integer,两者为同一个5
		System.out.println(a==c);//false,a取的是缓存中的5,c是新建的5对象,两者地址值不同
		System.out.println(d==e);//false,128已经超出缓存范围,java将新建128的Integer,
                                           d和e各自创建了一个128的Integer,地址值不同
		System.out.println(d==f);//false,理由同上,d和f各自创建了一个128的Integer对象,地址值不同
	}
5.Integer.parseInt
       parseInt(String s)只能将数字字符串转化十进制数,若要转化为其余进制数,则需要使用parseInt(String s, int radix)方法,第二个参数为指定的进制数
public static int parseInt(String s, int radix)
                throws NumberFormatException
    {    
        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) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') { 
                if (firstChar == '-') {
                    negative = true;//判断是否为负数
                    limit = Integer.MIN_VALUE;//将限制转换为Integer的最小值
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);//第一个char不为+也不为-,则抛出异常
                if (len == 1) 
                    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;
    }


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值