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

 

目录

基本数据类型包装类

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 stub
          Byte 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 iteration
        while (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);返回一个字符串,这样就传入一个字节,返回一个字符串
    

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java上位机程序的源码是指用Java语言编写的用于控制和监控外部设备的程序。以下是一个简单的Java上位机程序的源码示例: ```java import java.io.*; import java.util.*; public class UpperComputer { public static void main(String[] args) throws IOException { // 创建串口对象 SerialPort serialPort = new SerialPort("COM1"); // 打开串口 serialPort.openPort(); // 设置串口参数 serialPort.setParams(9600, 8, 1, 0); // 创建输入流 InputStream inputStream = serialPort.getInputStream(); // 创建输出流 OutputStream outputStream = serialPort.getOutputStream(); Scanner scanner = new Scanner(System.in); while (true) { // 读取传感器数据 byte[] data = new byte[8]; inputStream.read(data); System.out.println("收到传感器数据:" + Arrays.toString(data)); // 向外部设备发送指令 System.out.println("请输入指令:"); String command = scanner.nextLine(); outputStream.write(command.getBytes()); outputStream.flush(); } // 关闭串口 serialPort.closePort(); scanner.close(); inputStream.close(); outputStream.close(); } } ``` 上述代码基本实现了一个简单的Java上位机程序的功能,主要包括以下部分: 1. 导入相关的包。 2. 创建串口对象,并设置参数。 3. 创建输入流和输出流,用于与外部设备进行数据交互。 4. 使用循环不断读取传感器数据,并打印到控制台。 5. 从控制台接收指令,并发送给外部设备。 6. 在循环结束后关闭串口、输入输出流和输入流对象。 需要注意的是,这段代码只是一个简单的示例,实际的上位机程序可能会涉及更多的功能和复杂的逻辑。编写Java上位机程序需要根据具体的硬件设备和通信协议进行适配和调试,并确保程序的稳定性和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值