【java】java中进制、byte、String转换问题
在博主之前的文章中,有简单介绍过二进制,除了二进制,16进制也是常用的,例如在博主接触的tcp(modbus)协议中 16进制就经常出现。
如何发送byte数组指令
我们假设在对接中,知道固定的指令是16进制数组 代码示例如下:
// 16进制为例 byte rq = new byte[]{ 0x00,0x00,0x00,0x00,0x01,0x03} // 在netty中为例: channelHandlerContext.writeAndFlush(rq );
如何发送动态byte数组指令
上述例子中, 我们是知道指令的,而且指令是固定的,换句话说,byte数组里面的内容,是我们加上0x前缀写死的,那假设我们的指令并不是固定的,是可变的呢?
伪代码还原一下场景:
int id = ?; byte rq ; if (id == 3){ rq= new byte[]{ 0x00,0x00,0x00,0x00,0x01,0x03} } else if (id == 6){ rq= new byte[]{ 0x00,0x00,0x00,0x00,0x01,0x06} } else if(id == 9){ rq= new byte[]{ 0x00,0x00,0x00,0x00,0x01,0x09} }else{ // other }
如果id是有限个,我们还可以如上定义,那如果id是未知个呢? 如果基础比较差的同学可能会产生疑惑,不知道该如何定义了。
我们只需要直接将int强转byte就好了
rq= new byte[]{ 0x00,0x00,0x00,0x00,0x01,(byte) id};
byte和int互转问题
上文提到 int强转byte就好,但是byte和int之间互转会有个范围问题:
int t = 255; // (byte范围是-128-127) byte tt = (byte) t; // -1 // 而byte是可以直接转int的 int ttt = tt; // -1
可以看到byte为负数时,直接转回int就会出现问题了,那我们要如何得到int原来的数呢?我们需要将 tt 和 0xFF 做一次与运算,得到无符号数 (前提是知道int一定是正数)。
int res = tt & 0xFF; //255
说了那么多,可能有的同学会疑惑,为什么会出现byte范围的数据呢? 比如别人给过来的tcp数据格式是:00 00 00 00 00 04 01 02 03 FF ,(16进制),最后这个FF字节,就超过范围了。
科普一个小知识:大胆点,这个结果是true
byte和byte字符串互转问题
还是以16进制为例,我们需要引入hutool包,
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.0.7</version> </dependency>
// bytes to hexStr byte[] bytes = new byte[]{ 0x00,0x00,0x00,0x00,0x01}; String hexStr = HexUtil.encodeHexStr(bytes); // hexStr to bytes byte[] b = HexUtil.decodeHex(hexStr);
十进制转16进制字符串
String str = Integer.toHexString(11); // b
如果需要占两位长度 ,即: 0b ,则手动判断str的长度, 拼接一个0即可
str += "0"
还是有个常识性的问题,基础好的同学别看,看了反而会迷糊。
基础差的同学 可以看看: 我们只能手动声明0x 来表示16进制,但它并不是一个类型, 不能像10进制直接用long和int类型来表示
byte a = 0x01; // 16进制中01 的byte值 int b = 0x01; // 16进制中01 的int值
所以我们在代码中,一般都是用byte 或者String hexStr 来表示16进制, 还是那个例子 (byte) 0xFF 和 byte -1 值是相等的