为什么需要转换?
byte 数组在 Java 中通常用于处理二进制数据,如文件内容、网络数据包、加密后的数据等,而 16 进制字符串是一种人类可读的格式,常用于:

- 日志记录和调试
- 显示哈希值(如 MD5, SHA-256)
- 网络协议数据交换
- 配置文件中存储二进制数据
使用 javax.xml.bind.DatatypeConverter (JDK 1.7 及以下推荐)
这是在 Java 8 之前非常流行和方便的方法,因为它属于标准库的一部分,无需引入第三方依赖。
优点
- 简单直接:API 非常简洁。
- 无需依赖:是 Java 标准库的一部分。
缺点
- 已过时:自 Java 9 起,
javax.xml.bind包被标记为过时,并在 Java 11 中被完全移除,如果你使用的是新版本的 JDK,编译器会给出警告。 - 包名冗长:需要写一长串包名。
代码示例
import javax.xml.bind.DatatypeConverter;
public class ByteArrayToHexConverter {
public static void main(String[] args) {
byte[] bytes = { (byte) 0xFF, (byte) 0xA0, (byte) 0x01, (byte) 0x2B };
// 使用 DatatypeConverter 将 byte 数组转换为 16 进制字符串
String hexString = DatatypeConverter.printHexBinary(bytes);
System.out.println("转换后的 16 进制字符串: " + hexString);
// 输出: 转换后的 16 进制字符串: FFA0012B
}
}
使用 java.util.Base64 (JDK 8+ 推荐,但用于 Base64)
从 Java 8 开始,引入了 java.util.Base64 类,但它主要用于 Base64 编解码,虽然它不直接提供 16 进制转换,但了解它是好的。
注意:这个方法不适用于将
byte数组转换为 16 进制字符串,这里提及它只是为了澄清一个常见的误解,请使用下面的Hex类。
使用 Apache Commons Codec (最灵活、最推荐)
这是目前最常用、最灵活且社区支持最好的方法,它提供了一个专门的 Hex 工具类。

优点
- API 优秀:设计简洁,易于使用。
- 性能高:经过高度优化。
- 功能全面:不仅支持编码,还支持解码。
- 社区活跃:广泛使用,稳定可靠。
缺点
- 需要引入依赖:需要添加 Apache Commons Codec 的库到你的项目中。
如何添加依赖
Maven (pom.xml):
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version> <!-- 建议使用最新版本 -->
</dependency>
Gradle (build.gradle):
implementation 'commons-codec:commons-codec:1.15' // 建议使用最新版本
代码示例
import org.apache.commons.codec.binary.Hex;
public class ByteArrayToHexConverter {
public static void main(String[] args) {
byte[] bytes = { (byte) 0xFF, (byte) 0xA0, (byte) 0x01, (byte) 0x2B };
// 使用 Hex.encodeHexString() 方法
String hexString = Hex.encodeHexString(bytes);
System.out.println("转换后的 16 进制字符串: " + hexString);
// 输出: 转换后的 16 进制字符串: ffa0012b
// 如果需要大写字母
String upperHexString = Hex.encodeHexString(bytes).toUpperCase();
System.out.println("大写 16 进制字符串: " + upperHexString);
// 输出: 大写 16 进制字符串: FFA0012B
// 解码示例
byte[] decodedBytes = Hex.decodeHexString(hexString);
System.out.println("解码后的 byte 数组长度: " + decodedBytes.length);
}
}
手动实现 (不推荐,但有助于理解原理)
在某些极端情况下(如不能使用任何外部库),你可能需要自己实现转换逻辑。
优点
- 无任何依赖:纯 Java 实现。
- 有助于学习:能让你理解底层转换过程。
缺点
- 代码冗长:需要自己处理循环、格式化和异常。
- 容易出错:需要正确处理负数
byte和补零。 - 性能较差:通常没有优化过的库性能高。
代码示例
public class ByteArrayToHexConverter {
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static void main(String[] args) {
byte[] bytes = { (byte) 0xFF, (byte) 0xA0, (byte) 0x01, (byte) 0x2B };
String hexString = bytesToHex(bytes);
System.out.println("手动转换后的 16 进制字符串: " + hexString);
// 输出: 手动转换后的 16 进制字符串: FFA0012B
}
public static String bytesToHex(byte[] bytes) {
if (bytes == null) {
return null;
}
char[] hexChars = new char[bytes.length * 2];
for (int i = 0; i < bytes.length; i++) {
// 将 byte 转换为无符号的 int 值 (0-255)
int v = bytes[i] & 0xFF;
// 取高 4 位
hexChars[i * 2] = HEX_ARRAY[v >>> 4];
// 取低 4 位
hexChars[i * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
}
关键点:bytes[i] & 0xFF 是最关键的一步,Java 的 byte 是有符号的(范围是 -128 到 127),通过与 0xFF(二进制 11111111)进行位与操作,可以将其转换为 0 到 255 之间的无符号整数,这样才能正确映射到 16 进制字符。

总结与选择建议
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
javax.xml.bind.DatatypeConverter |
简单,无依赖 | 已过时,JDK 11+ 需额外配置 | 不推荐,仅用于维护旧项目(JDK 8-) |
| Apache Commons Codec | API优秀,性能高,功能全 | 需要引入外部依赖 | 强烈推荐,新项目首选 |
| 手动实现 | 无依赖,有助于学习 | 代码冗长,易出错,性能低 | 学习目的,或项目有严格的依赖限制 |
java.util.Base64 |
标准库,无依赖 | 用于 Base64,不用于 16 进制 | 需要编码 Base64 时使用 |
最终建议:
- 对于所有新项目,请优先使用 Apache Commons Codec,它的稳定性和易用性是最好的。
- 如果你正在维护一个旧项目,并且使用的是 JDK 8 或更早版本,
javax.xml.bind.DatatypeConverter是一个可接受的快速解决方案。 - 尽量避免手动实现,除非你完全理解其原理并且有特殊要求。
