该文章对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