菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
397
0

java Integer类源码阅读

原创
05/13 14:22
阅读数 74437

该文章对Integer类源代码中的重点、难点代码段进行分析。对于源代码中比较简单的部分不再赘述,有需要的可以直接查看源代码。

 

Integer::stringSize(int x) 计算一个int类型的数值转换成字符串后长度为多少
 1 static int stringSize(int x) {
 2     // d的值为1,代表负数的负号占用1个长度
 3     int d = 1;
 4     // 如果x为正数,则将x统一为负数,方便后续进行统一的操作
 5     // 为什么统一成负数?因为正数的最大值的绝对值比负数最小值的绝对值小1,
 6     // 若 x=Integer.MIN_VALUE 则 x=-x 会报错
 7     if (x >= 0) {
 8         d = 0;
 9         x = -x;
10     }
11     // p是一个比较基准值,当i=1时,如果x>p(-10),再加上x为负数,则可以确定x绝对值只有1位;
12     // 同理,当i=2时,如果x>p(-100),再加上x为负数,则可以确定x绝对值只有2位;
13     // 可知,当i=i时,如果x>p(-10*(i-1)),再加上x为负数,则可以确定x绝对值有i位;
14     // i的取值为1~10,因为int的二进制表示为32位,-2^32=-4,294,967,296,数字为最多为十位,i循环到10足够用了
15     int p = -10;
16     for (int i = 1; i < 10; i++) {
17         if (x > p)
18             return i + d;
19         p = 10 * p;
20     }
21     return 10 + d;
22 }

 

Integer::getChars(int i, int index, byte[] buf) 将十进制数字i转换成比特串buf
 1 static int getChars(int i, int index, byte[] buf) {
 2         int q, r;
 3         int charPos = index;
 4 
 5         boolean negative = i < 0;
 6         // 如果当前的数为正数,则统一为负数(0不变就行)
 7         // 因为int类型最大值的绝对值比最小值的绝对值小,所以统一成正数会出问题
 8         if (!negative) {
 9             i = -i;
10         }
11 
12         // 当确定i<=-100时,一次迭代生成两个字符加速运行
13         while (i <= -100) {
14             // 例子:i = -121 => q = -1, r = -100 - (-121) = 21, 正好提取出后两位
15             q = i / 100;
16             r = (q * 100) - i;
17             i = q;
18             buf[--charPos] = DigitOnes[r]; // 写入个位字符
19             buf[--charPos] = DigitTens[r]; // 写入十位字符
20         }
21 
22         // 执行到这里i一定是一个小于两位的负的十进制数,所以无法一次处理两位,所以一位一位的处理完剩下的0~2位
23         // We know there are at most two digits left at this point.
24         q = i / 10;
25         r = (q * 10) - i;
26         buf[--charPos] = (byte)('0' + r);
27 
28         // Whatever left is the remaining digit.
29         if (q < 0) {
30             buf[--charPos] = (byte)('0' - q);
31         }
32 
33         // 为负数添加负号字符
34         if (negative) {
35             buf[--charPos] = (byte)'-';
36         }
37         return charPos;
38     }
39 
40 // 当i为一个2位十进制数时DigitTens[i]=该数的十位的数字对应的字符
41 static final byte[] DigitTens = {
42     '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
43     '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
44     '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
45     '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
46     '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
47     '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
48     '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
49     '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
50     '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
51     '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
52     } ;
53 
54 // 当i为一个2位十进制数时DigitTens[i]=该数的个位的数字对应的字符
55 static final byte[] DigitOnes = {
56     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
57     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
58     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
59     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
60     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
61     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
62     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
63     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
64     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
65     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
66     } ;

 

Integer.toString(int i) 静态方法,将一个十进制的整数i转换成字符串表示
@HotSpotIntrinsicCandidate // 次注解表明该方法在hotspot虚拟机中有一套c语言代码实现
public static String toString(int i) {
    int size = stringSize(i);
    // COMPACT_STRINGS表示是否使用紧凑布局的字符编码方式
    // 紧凑布局采用LATIN1编码方式,每个字符占用8bit
    // 非紧凑布局采用UTF16编码方式,每个字符占用16bit
    // 因此非紧凑布局的buf长度为紧凑布局的2倍
    if (COMPACT_STRINGS) {
        byte[] buf = new byte[size];
        getChars(i, size, buf);
        return new String(buf, LATIN1);
    } else {
        byte[] buf = new byte[size * 2];
        StringUTF16.getChars(i, size, buf);
        return new String(buf, UTF16);
    }
}

 

发表评论

0/200
397 点赞
0 评论
收藏