Integer.toHexString((byteVar & 0x000000FF) | 0xFFFFFF00).substring(6)解释

本文详细介绍了如何将Java中的字节值转换为十六进制表示,并通过多种方法展示不同场景下字节转换的技巧。包括负数、正数及二进制与十六进制之间的相互转换。

为了显示一个byte型的单字节十六进制(两位十六进制表示)的编码,请使用:

Integer.toHexString((byteVar & 0x000000FF) | 0xFFFFFF00).substring(6)

byteVar & 0x000000FF的作用是,如果byteVar 是负数,则会清除前面24个零,正的byte整型不受影响。(...) | 0xFFFFFF00的作用是,如果byteVar 是正数,则置前24位为一,这样toHexString输出一个小于等于15的byte整型的十六进制时,倒数第二位为零且不会被丢弃,这样可以通过substring方法进行截取最后两位即可。

package des;

import junit.framework.TestCase;

public class Hex extends TestCase {   
   
    public void testPositiveIntToHex() {   
        //如果正数小于15时,只输入一位,而不是按我们想像的两位标准十六进制输出显示的,后面解决这个问题   
        System.out.println(Integer.toHexString(2));//2   
        System.out.println(Integer.toHexString(15));//f   
        System.out.println(Integer.toHexString(16));//10   
        System.out.println(Integer.valueOf("F", 16));//16   
    }   

    /* 
     * Integer.valueOf()实质上调用的是Integer.parseInt()来完成的,所以 
     * Integer.parseInt()与Integer.valueOf()功能是一样的,只是返回值不 
     * 一样而已 
     */ 
    public void testNegativeIntToHex() {   
        //负整数时,前面输入了多余的 FF ,没有去掉前面多余的 FF,按并双字节形式输出   
        System.out.println(Integer.toHexString(-2).toUpperCase());//FFFFFFFE   

        //实质上0xFF会像转换成0x000000FF后再进行位运算   
        System.out.println(Integer.toHexString(-2 & 0xFF).toUpperCase());//FE   
        System.out.println(Integer.toHexString(-2 & 0x000000FF).toUpperCase());//FE   

        //注,FE输出时不会为-2,因为此时不会把FE看成负数,valueOf会把所有数字串看成正的   
        System.out.println(Integer.valueOf("FE", 16));//254   
        //如果要输出-2,只能按以下形式输出   
        System.out.println(Integer.valueOf("-2", 16));//-2   

        //所以要把 FE 看成负的话,只能在前面加上负号,但是这里输出还不是-2,   
        //而是先计算Integer.valueOf("FE", 16),再在结果前加上负   
        System.out.println(Integer.valueOf("-FE", 16));//-254   

        /* 所以如果要输入某个负数,我们只能先求出该数的绝对值的原码十六进制,再在前面加上负号, 
         * 例如求表示-128,则先对绝对值128求十六进制 80,再在前面加上负号 -80 
         */ 
        System.out.println(Integer.valueOf("-80", 16));//-128   

        /* 为什么说valueOf把所有数字串看成正的呢?请看下面三行代码,因为最大正数为2147483647, 
         * 如果再 在7fffffff基础上加上一个一,运行肯定会出错误(这与直接输出0x80000000不一样), 
         * 那么就可以证明 
         */ 
        System.out.println(Integer.valueOf("7fffffff", 16));//2147483647   
        //此句运行时会报错,因为最大正数为7fffffff,但如 -80000000 却又可以运行,因为没超出整数范围   
        //System.out.println(Integer.valueOf("80000000", 16));//不能运行,已注掉   
        System.out.println(Integer.valueOf("-80000000", 16));//-2147483648   

        /* 注,输出时不是负数,而是正,因为0xFE只有8位,而整数是32位,所以以int形式出现时前 
         * 面会自动补24个零,第一位是零,所以最后是正数 
         */ 
        System.out.println(0xFE);//254   
        System.out.println(-0xFE);//-254   
        //但0x80000000已满,无需补,第一位为一,所以最后为负数   
        System.out.println(0x80000000);//-2147483648   
    }   

    public void testNegativeIntToBin() {   
        System.out.println(Integer.toBinaryString(-2));//11111111111111111111111111111110   
        //实质上0xFF会像转换成0x000000FF后再进行位运算   
        System.out.println(Integer.toBinaryString(-2 & 0xFF));//11111110   
        System.out.println(Integer.toBinaryString(-2 & 0x000000FF));//11111110   

        //与上面十六进制是一样的   
        System.out.println(Integer.valueOf("1111111111111111111111111111111", 2));//2147483647   
        //下面语句运行会出错,已注掉   
        //System.out.println(Integer.valueOf("10000000000000000000000000000000", 2));   
        System.out.println(Integer.valueOf("-10000000000000000000000000000000", 2));//-2147483648   
        System.out.println(Integer.valueOf("11111110", 2));//254   
        System.out.println(Integer.valueOf("-11111110", 2));//-254   

        /* 注,Java中没有直接使用二进制表示一个数(目前只支持八与十六进制直接表示法),下面其实是一个 
         * 八进制的数与十进制的数 
         */ 
        System.out.println(010);//8   
        System.out.println(10);//10   
    }   

    public void testByteToHex() {   

        byte negativeByte = -2;   
        byte positiveByte = 2;   

        /* toHexString方法类型为int型,所以转Hex前参数会提升成整型后再进行转换,过程如下: 
         * 10000010(原码)->11111110(补码)->11111111 11111111 11111111 11111110(提升) 
         * ->FFFFFFFE(转Hex进制输出) 
         */ 
        System.out.println(Integer.toHexString(negativeByte).toUpperCase());// FFFFFFFE   

        /* 第一步把-2转成整型: 
         * 10000010(原码)->11111110(补码)->11111111 11111111 11111111 11111110(转整型) 
         * 第二步把 0xFF 前补24个零: 
         * 00000000 00000000 00000000 11111111 
         * 第三步:把第一二步结果进行与位运算: 
         * 00000000 00000000 00000000 11111110 
         * 最后一步:转十六进制结果为 FE   
         */ 
        System.out.println(Integer.toHexString(negativeByte & 0xFF).toUpperCase());// FE           

        //另一种转换,可以针对负数与正数的byte都可以以完整的单字节输出   
        System.out.println(Integer.toHexString((negativeByte & 0x000000ff) | 0xffffff00)   
                .substring(6).toUpperCase());//FE   
        System.out.println(Integer.toHexString((positiveByte & 0x000000ff) | 0xffffff00)   
                .substring(6).toUpperCase());//02   
    }   

    /** 
     * 位运算与算术运行中的类型提升机制是一样的 
     */ 
    public void testBiteMathematical() {   
        System.out.println(0x8000000000000000L);//-9223372036854775808   
        System.out.println((int) 0x8000000000000000L);//0   
        System.out.println(0x8000000000000010L);//-9223372036854775792   
        System.out.println(0x80000000);//-2147483648    
        System.out.println(0x80000010);//-2147483632    

        //0x00000010提升成长整型,最后结果为长整型0x8000000000000010L   
        System.out.println(0x00000010 | 0x8000000000000000L);//-9223372036854775792   
        //0x0010提升成整形,最后结果为整型0x80000010   
        System.out.println(0x0010 | 0x80000000);//-2147483632    
    }   
}


转自 http://hi.baidu.com/slandi/blog/item/f7b77008e8fb78c13ac7633a.html

<think>首先,用户的问题是关于Java代码的含义:`Integer.toHexString(i & 0xFF)`。用户想知道这个代码的具体含义。 从系统指令中,我必须遵循格式要求:行内数学表达式使用 `$...$`,独立公式使用 `$$...$$`,语法正确,用中文回答,生成相关问题。 用户提供了多个引用:[^1] 到 [^5]。我需要参考这些引用来回答。让我总结一下这些引用: - [^1]:解释 `Integer.toHexString` 是把字节以16进制方式显示的方法,参数是int类型。 - [^2]:提到如何显示byte类型的单字节十六进制编码,使用 `Integer.toHexString((byteVar & 0x000000FF) | 0xFFFFFF00)`,但用户的问题中是 `i & 0xFF`,可能i是int类型。 - [^3]:解释为什么加 `& 0xFF`:因为 `toHexString` 需要int类型,byte只有8位,int是32位,需要转换。 - [^4]:详细解释:`toHexString` 参数是int,32位。byte是8位,所以添加 `& 0xFF` 来只保留后8位,去除高位。 - [^5]:更深入解释:当byte是负数时,直接转换为int会符号扩展,高位填充1,导致16进制表示不正确。`& 0xFF` 确保只取低8位,忽略高位,这样对于byte值(0-255),能正确显示为两位十六进制。 用户的问题中写的是 `i & 0xFF`,但在引用中多是针对byte类型。用户说 `i`,可能是个变量名。在引用[^3]和[^5]中,提到byte数组,但用户的问题是 `i & 0xFF`,所以我需要澄清。 在用户的消息中:"Integer.toHexString(i & 0XFF)",用户写了 `i`,可能是个int变量。但在上下文中,引用讨论的是byte类型。让我检查用户的问题:"我想了解JavaInteger.toHexString(i & 0XFF)代码的含义",它用的是 `i`,而不是 `b`。在引用中,大多是 `b` for byte。 回顾引用: - [^1]:`Integer.toHexString(b & 0xff)` with b as byte. - [^2]:`byteVar` - [^3]:`b[n] & 0XFF` - [^4]:`b & 0xff` - [^5]:`b[i] & 0xFF` 所以引用主要讨论的是当输入是byte类型时,为什么要加 `& 0xFF`。 但在用户的问题中,变量是 `i`,这可能是一个int。用户说:"i & 0XFF",所以 `i` 可能是一个int变量。 我需要回答基于这个。可能用户误解了,或者 `i` 是代表整数。 在Java中,`Integer.toHexString(int i)` 方法接受一个int参数。`& 0xFF` 是一个位操作,将int的低8位保留,高位设置为0。 所以,对于任意int值 `i`,`i & 0xFF` 会返回一个int值,范围在0到255之间,因为 `0xFF` 是十六进制的255,二进制是11111111(8位1)。 然后 `Integer.toHexString(i & 0xFF)` 会返回这个8位值的十六进制字符串表示,总是两位十六进制数字(除非小于16,可能是一位,但通常用两位表示,例如 "0f")。 引用[^5]解释了当处理byte值时,为什么需要这个操作:因为byte在转换为int时,如果byte是负数,会有符号扩展问题。 但用户的问题是 `i & 0xFF`,所以 `i` 可能已经是int。 在回答中,我应该解释代码的含义,参考引用。 含义总结: - `Integer.toHexString(int i)`:将整数i转换为十六进制字符串表示。 - `& 0xFF`:位与操作,0xFF是255,二进制低8位都是1,高位0。所以 `i & 0xFF` 只保留i的低8位,高位设置为0。 - 因此,`Integer.toHexString(i & 0xFF)` 返回i的低8位的值的十六进制字符串,总是两位(例如 "ff" for 255)。 在上下文中,常用于处理byte值,因为byte是8位,但toHexString需要int,所以 `(byteValue) & 0xFF` 确保正确转换。 回答结构: 1. **解释代码含义**:用中文解释。 2. **引用参考**:使用给定的引用,在末尾添加引用标识。 3. **生成相关问题**:根据系统指令,生成相关问题。 4. **格式**:行内数学表达式如位操作使用 `$...$`,如果有公式单独使用 `$$...$$`。 例如,位操作解释:`&` 是位与操作,0xFF 是 $255_{10}$ 或 $11111111_2$。 数学表达式:对于整数转换。 在回答中自然地添加引用。 完整回答: - 开头概述代码含义。 - 详细解释为什么需要 `& 0xFF`,特别是当处理byte时。 - 给出示例。 - 结尾添加相关问题。 生成相关问题: 1. 当处理byte值时,为什么不直接使用 `Integer.toHexString(byteValue)`? 2. 如何确保十六进制输出总是两位? 3. 在其他编程语言中,类似操作如何实现? </think>### Java中`Integer.toHexString(i & 0xFF)`代码的含义 在Java中,`Integer.toHexString(i & 0xFF)` 是一个常见的代码片段,主要用于将整数值的低8位转换为一个两位的十六进制字符串表示。下面我将逐步解释其含义和工作原理,确保回答清晰可靠。其中,`i` 通常代表一个整型变量(int类型),但代码常用于处理byte值(如从字节数组读取数据)。我会参考您提供的引用([^1] 到 [^5])来支持解释。 #### 1. **代码组件详解** - **`Integer.toHexString(int i)`**:这是Java标准库的一个静态方法,用于将整型参数 `i` 转换为十六进制字符串。例如: - `Integer.toHexString(255)` 返回字符串 "ff"。 - `Integer.toHexString(10)` 返回字符串 "a"(注意:输出可能不是固定两位,取决于输入值)[^1][^4]。 - **`& 0xFF`**:这是一个位与(bitwise AND)操作: - `0xFF` 是十六进制的字面量,等价于十进制的255($255_{10}$)或二进制的 $11111111_2$(8位全1)。 - 位与操作 `i & 0xFF` 会保留 `i` 的低8位(least significant bits),并将高位(high bits)全部设置为0。数学上,这可以表示为: $$ (i \ \text{AND} \ 0\text{xFF}) \rightarrow \text{结果是一个值在 } [0, 255] \text{ 范围内的整数} $$ - 例如: - 如果 `i = 300`(二进制 $00000000\ 00000000\ 00000001\ 00101100_2$),则 `i & 0xFF` 计算为 $00000000\ 00000000\ 00000000\ 00101100_2$(即44),十六进制为 "2c"。 - 如果 `i = -1`(二进制 $11111111\ 11111111\ 11111111\ 11111111_2$),则 `i & 0xFF` 计算为 $00000000\ 00000000\ 00000000\ 11111111_2$(即255),十六进制为 "ff"[^4][^5]。 因此,`Integer.toHexString(i & 0xFF)` 的整体含义是:**提取整数 `i` 的低8位值(范围0-255),并将其转换为两位的十六进制字符串(如果需要,前导零会自动添加)**。 #### 2. **为什么需要 `& 0xFF`?** - **确保正确转换低8位**:`Integer.toHexString()` 方法要求参数是int类型(32位),但当输入类似byte值(8位)时,Java会自动将byte提升为int。如果原值是负数,这种提升会导致符号扩展(sign extension),即高位填充1,而不是0: - 例如,byte值 `-12`(二进制 $11110100_2$)提升为int时,会变成 $11111111\ 11111111\ 11111111\ 11110100_2$(即-12的补码表示)。直接调用 `Integer.toHexString(-12)` 会返回 "fffffff4",而不是期望的单字节值 "f4"。 - 添加 `& 0xFF` 后: `(-12) & 0xFF` 结果为 $00000000\ 00000000\ 00000000\ 11110100_2$(即244),然后 `Integer.toHexString(244)` 返回 "f4",这正是byte值 `-12` 的正确十六进制表示[^3][^5]。 - **处理byte值时的关键作用**:在加密、网络传输或二进制数据处理中,常用byte数组存储单字节数据(如像素值或密钥)。`& 0xFF` 确保: - 只保留低8位,忽略高位(相当于“补零扩展”,而不是符号扩展)。 - 输出总是两位十六进制数字(例如,"0a" 而不是 "a"),便于统一格式显示或存储[^2][^4][^5]。 - **数学基础**:位与操作本质是模运算的简化。`i & 0xFF` 等价于 $i \mod 256$(因为256是 $2^8$),但这仅限于非负整数;对于负数,位与操作更高效,因为它直接操作二进制位[^4]。 #### 3. **常见使用场景示例** - **处理byte数组时的典型代码**(如引用[^3][^5]所述): ```java byte[] data = { (byte) 0xAB, (byte) 0xFF, (byte) 0x1A }; // 示例byte数组 for (byte b : data) { String hex = Integer.toHexString(b & 0xFF); // 确保正确转换每个byte System.out.println(hex); // 输出: "ab", "ff", "1a" } ``` 这里,`b & 0xFF` 将每个byte值安全转换为0-255范围内的整数,然后 `toHexString` 生成两位十六进制字符串。 - **如果省略 `& 0xFF` 的风险**:如果 `i` 是高值int或负数,直接 `Integer.toHexString(i)` 可能返回4-8位十六进制字符串(如 "ffffffff"),而非预期的两位值。`& 0xFF` 强制截断到8位,保证输出长度一致[^1][^5]。 #### 4. **总结** `Integer.toHexString(i & 0xFF)` 的核心目的是**可靠地将任意整数的低8位转换为两位十六进制字符串**,特别适用于处理byte数据,避免符号扩展导致的错误。这得益于位与操作 `& 0xFF` 的二进制截断特性,确保结果在0-255范围内。在Java二进制数据处理中,这是一种标准且高效的做法[^4][^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值