byte转16进制String时为什么要乘上0xff

基本知识

1.byte是1byte(8位),int是4byte(32位)表示的。
2.Java中是使用了补码的形式进行数据存储的。
3.java中byte数据转化为int数据时会自动补位,如果最高位(符号位)是0,则高24位全部补0,若是1,则高24位全部补1。

原因解析

如下代码:

public static String parseByte2HexStr(byte[] buf) {
    
    
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
    
    
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
    
    
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

正数

一个正数byte,转为int时,前面补0。得到的依然是正数,而且值不变。
比如:1
byte 1=0000 0001 。转为int 前面补0得到 0000 0000 0000 0000 0000 0000 0000 0001。所以做不做&0xff运算都一样,保存的16进制都是0x01。

负数

负数byte,转为int时,java为了保持值不变,默认前面补1。
比如:-1
byte -1二进制以补码保存 11111 11111 。转为int 前面补1得到 1111 1111 1111 1111 1111 1111 1111 1111。这个值在int确实是-1,但是如果Integer.toHexString()保存为16进制得到0xffff ffff。当然我们可以用这个数保存-1。

byte  i=(byte) (0xffffffff)
i=-1;

但是会有两个问题:1、保存的字符长度难以统一 2、字符串长度太长。
byte的取值范围在[-128,127]之间,16进制表示用两个符号就够了0x00—0xff。负数如果用这么多字符,造成正负数符号长度不统一怎么保存呢?从16进制还原成2进制时怎么按长度区分各个数字呢?

所以我们把byte与运算&0xff。以-1为例:1111 1111 1111 1111 1111 1111 1111 1111 & 0xff 得到 0000 0000 0000 0000 0000 0000 1111 1111 即0xff。这个数结果依然是-1。

byte  i=(byte) (0xff)
i=-1;

用这种方式处理后,byte不论正负,得到的都是二位的16进制数。以两位存储,两位还原,很方便。
也可以这样还原。

以ff的16进制数保存:
byte i=(byte) (high * 16 + low);
i=-1;

猜你喜欢

转载自blog.csdn.net/qq_38205881/article/details/109178030