当前位置: 代码迷 >> 综合 >> java中的Byte对象源码之一toString()
  详细解决方案

java中的Byte对象源码之一toString()

热度:26   发布时间:2023-10-31 16:25:02.0

 

目录

基本数据类型包装类

Byte源码研读

toString()源码研读


基本数据类型包装类

所谓万事万物皆对象,所以其实我们的基本数据类型也有针对性类的描述

byte-Byte 

short-Short

int-Integer

long-Long

float-Float

double-Double

char-Character

boolean-Boolean

这些类的基类都是Number

Byte源码研读

     ----------------toString()源码研读

package Integer;public class IntegerDemo {public static void main(String[] args) {// TODO Auto-generated method stubByte b=new Byte("123");byte m=7;     System.out.println(b.toString(m));}}

我们先来看Byte类中的toString方法

我们进入到Byte类的源码中找到这个toString()的源码,找到toString()的方法

 public static String toString(byte b) {return Integer.toString((int)b, 10);}

这个方法它是返回的Integer中的toString()方法,再去切到Integer类中toString()方法看下

 public static String toString(int i, int radix) {if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)radix = 10;/* Use the faster version */if (radix == 10) {return toString(i);}char buf[] = new char[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] = '-';}return new String(buf, charPos, (33 - charPos));}

因为我们的radix==10,代表的就是10进制, 通过这个if(radix==10){return toString(i)},我们看到如果是十进制,返回的是toStirng()这个方法,我们再切进去看下这个方法

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

切进来我们看到,因为我们的i==7,所以size的值等于这个stringSize(i),我们再切进stringSize(i)里面看下

 static int stringSize(int x) {for (int i=0; ; i++)if (x <= sizeTable[i])return i+1;}

进来我们看到只有x值小于等于sizeTable[i],就会返回i+1,我们的x值是7,来看下sizeTable[i]是多少,i是从0开始的

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,99999999, 999999999, Integer.MAX_VALUE };

因为我们的x==7<sizeTable[0]==9,所以size==i+1==1, 然后就是建立一个char [] buf =new char[size],建立一个长度为1的字符数组,

然后在进入到getChars(i.size,buf)方法里面,此时i==7,size==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;}// Generate two digits per iterationwhile (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;}}

因为i==7,所以我们会进入这个代码块中

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

 

进入for循环,这是匪夷所思的代码: 
q = (i * 52429) >>> (16+3); 
这个(i * 52429) >>> (16+3)到底是想干什么? 
右移16+3也就是右移19位,也就是除以2的19次方,2的19次方=524288,所以

(i * 52429) >>> (16+3)
= (i * 52429) / 2的19次方
= (i * 52429) / 524288
= i * (52429 / 524288)
= i * 0.1000003814697266
= i * 0.1
这个0.1000003814697266的精度已经很多了,就几乎等于0.1。 
所以算了这么多,这行代码其实就是q = i / 10,还是为了避免乘除法,提高运算效率。

所以q=7/10==0

至于为什么选择2的19次方524288,是因为52429/524288得到的数字精度在不超出整形范围内,精度是最高的。 
如果选择2的17次方131072,那么13108 / 131072 = 0.100006103515625, 
或者选择2的18次方262144,那么26215 / 262144 = 0.1000022888183594, 
或者选择2的20次方1048576,那么104858 / 1048576 = 0.1000003814697266, 
所得到的精度都不可能更高了。

然后下面的代码就很清楚了: 
r = i - ((q << 3) + (q << 1)); 
意思就是r = i-(q*10),也就是r等于i除以10得到的余数。 

所以r=7
然后再到buf [--charPos] = digits [r];这段代码,我们先来看下digis这个数组

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

 因为charPos==1,所以buf[--charPos]==buf[0]=digits[7]==7,buf数组存的数值就是字符7,然后再把i=q,就是把0给i,当i等于0时,程序结束,最终return new String(buf, true);返回一个字符串,这样就传入一个字节,返回一个字符串