java Integer.toString源码分析

474 阅读1分钟

Integer.toString()源码分析

public static String toString(int i) {
    if (i == Integer.MIN_VALUE)
        //最小整数 32位 一位符号位-2^31
        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 int stringSize(int x) {
    for (int i=0; ; i++)
        if (x <= sizeTable[i])
            return i+1;
}
//最高到10位 之后的所有都按照10截断
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                  99999999, 999999999, Integer.MAX_VALUE };
static void getChars(int i, int index, char[] buf) {
    int q, r;
    int charPos = index;
    //符号位
    char sign = 0;

    //如果i为负数
    if (i < 0) {
        //添加负号
        sign = '-';
        //将负数取正
        i = -i;
    }

    // Generate two digits per iteration
    //官方注释翻译:每次迭代生成两位数
    //65536 2的16次方
    while (i >= 65536) {
        //注意:此时q类型为int q的值会去掉小数后的数取整 
        //若此时i=65536 则i/100=655.36 由于q为int类型则q实际上的值=655 小数点后面的数会被截断
        q = i / 100;
    // really: r = i - (q * 100);
    //官方注释翻译:正真的意思:r = i - (q * 100)
    //<<左移位运算 q<<6表示q*2^6=q*64 同理q<<5表示q*32 q<<2表示q*4 相加刚好等于q*100 
    //接着上面的例子q=655 那么r=i-(q*100)=65536-(655*100)=36 即r为i的最后面的两位数
        r = i - ((q << 6) + (q << 5) + (q << 2));
        
        i = q;
        //接着上面的例子 index其实是stringsize i=65536 则 charPos=5 此时buf[4]=6
        buf [--charPos] = DigitOnes[r];
        buf [--charPos] = DigitTens[r];
    }

    // Fall thru to fast mode for smaller numbers
    // 官方注释翻译:下降到快速模式以获取较小的数字
    // assert(i <= 65536, i);
    for (;;) {
        //(i * 52429) / (2^19) (i * 52429) / 524288 不考虑余数为10
        //i=655 i%10
        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=36 此时应该是索引为36的字符 从0开始一排10个 第一排0-9 第二排10-19 第三排20-29 第四排 30-39依次类推 
//我们发现这个数组索引对应的永远的都是索引的最后一位 所以DigitOnes[36]=6(第4排的)
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 [] 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',
    } ;

引用:源码分析

标题:头条三面:toString()、String.valueOf、(String)强转,有啥区别? - 掘金

网址:juejin.cn/post/707365…