核心概念:字符编码
计算机只认识 0 和 1。byte 8 个 0 或 1 的组合。String 是人类可读的字符(如 'A', '中', '€')。byte 到 String 的转换,本质上是如何将一串 0 和 1 解释成特定的字符。

这个“解释规则”就是字符编码,
- ISO-8859-1 (Latin-1): 单字节编码,支持西欧语言,不支持中文。
- GBK / GB2312: 中国国家标准编码,支持大部分中文字符。
- UTF-8: 目前互联网上最通用的编码,使用 1 到 4 个字节表示一个字符,兼容 ASCII,是国际标准。
- UTF-16: Java 内部使用的编码,使用 2 或 4 个字节表示一个字符。
关键点:编码和解码必须使用同一种规则,否则一定会出现乱码。
单个 byte 转 String
如果你只有一个 byte,并且你知道它代表的字符的编码,可以直接使用 String 的构造方法。
public class ByteToString {
public static void main(String[] args) {
byte myByte = 65; // ASCII 码中 65 代表 'A'
// 1. 假设这个 byte 是 ASCII 或 ISO-8859-1 编码
// 这是最常见和最安全的方式,因为它们完全兼容
String strFromByte = new String(new byte[]{myByte}, StandardCharsets.US_ASCII);
// 或者
// String strFromByte = new String(new byte[]{myByte}, "ISO-8859-1");
System.out.println("单个 byte 转换为 String: " + strFromByte); // 输出: A
// 2. 错误的示范:如果这个 byte 实际上是 GBK 编码的一部分
// 比如一个中文字符 '中' 在 GBK 中是两个字节:-42, -48
// 如果你只取其中一个 byte -42,并用 ASCII 解码,会得到乱码
byte chineseBytePart = -42;
String wrongStr = new String(new byte[]{chineseBytePart}, StandardCharsets.US_ASCII);
System.out.println("错误编码示范: " + wrongStr); // 输出: ? (一个乱码符号)
}
}
单个 byte 转 String 意义不大,通常它只是多字节字符的一部分,除非你明确知道这个 byte 在特定编码(如 ASCII)下的含义。

byte[] 转 String(最常见的情况)
这是最常见的需求,比如从网络读取数据、读取文件内容等,这里必须指定正确的编码。
推荐方式 - 使用 StandardCharsets (Java 7+)
这是最安全、最推荐的方法,因为它避免了拼写错误,并且性能更好。
import java.nio.charset.StandardCharsets;
public class ByteArrayToString {
public static void main(String[] args) {
// 一个包含 "Hello, 世界!" 的 UTF-8 编码的字节数组
byte[] utf8Bytes = {(byte) 72, (byte) 101, (byte) 108, (byte) 108, (byte) 111, (byte) 44, (byte) 32,
(byte) -28, (byte) -72, (byte) -83, (byte) -27, (byte) -101, (byte) -67};
// 正确方式:使用 UTF-8 编码进行转换
String correctStr = new String(utf8Bytes, StandardCharsets.UTF_8);
System.out.println("正确转换 (UTF-8): " + correctStr); // 输出: Hello, 世界!
// 错误示范:如果数据是 UTF-8,但你用 ISO-8859-1 解码
String wrongStr = new String(utf8Bytes, StandardCharsets.ISO_8859_1);
System.out.println("错误转换 (ISO-8859-1): " + wrongStr); // 输出: Hello, 世界! (乱码)
}
}
传统方式 - 使用 String 构造方法和编码名称
如果你使用的是 Java 7 之前的版本,或者需要动态指定编码名称,可以使用这种方式。
public class ByteArrayToStringLegacy {
public static void main(String[] args) {
byte[] utf8Bytes = {(byte) 72, (byte) 101, (byte) 108, (byte) 108, (byte) 111, (byte) 44, (byte) 32,
(byte) -28, (byte) -72, (byte) -83, (byte) -27, (byte) -101, (byte) -67};
try {
// 正确方式
String correctStr = new String(utf8Bytes, "UTF-8");
System.out.println("正确转换 (UTF-8): " + correctStr); // 输出: Hello, 世界!
// 错误示范
String wrongStr = new String(utf8Bytes, "ISO-8859-1");
System.out.println("错误转换 (ISO-8859-1): " + wrongStr); // 输出: Hello, 世畎! (乱码)
} catch (UnsupportedEncodingException e) {
// 如果指定的编码不被支持,会抛出此异常
e.printStackTrace();
}
}
}
String 转 byte[](反向操作)
理解了 byte[] 转 String,反向操作就很简单了,同样需要指定编码。

import java.nio.charset.StandardCharsets;
public class StringToByteArray {
public static void main(String[] args) {
String str = "Hello, 世界!";
// 1. 使用 StandardCharsets.UTF_8 推荐方式
byte[] utf8Bytes = str.getBytes(StandardCharsets.UTF_8);
System.out.println("String 转 byte[] (UTF-8):");
// 打印字节数组内容
for (byte b : utf8Bytes) {
System.out.print(b + " ");
}
System.out.println("\n");
// 2. 使用传统方式
try {
byte[] gbkBytes = str.getBytes("GBK"); // 假设目标系统支持 GBK
System.out.println("String 转 byte[] (GBK):");
for (byte b : gbkBytes) {
System.out.print(b + " ");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
处理二进制数据(如图片、文件)
byte[] 代表的不是文本,而是纯粹的二进制数据(如图片、PDF、加密数据),在这种情况下,不应该尝试将其转换为 String,因为:
- 数据损坏:二进制数据中可能包含任何值的字节(包括负数),它们可能不是有效的 UTF-8 或 GBK 序列,强制转换会导致数据丢失或损坏。
- 无意义:将图片转换成字符串是没有意义的,它只是一堆无法阅读的字符。
正确做法:直接处理 byte[] 数组,或者如果需要传输/存储,可以使用 Base64 对其进行编码,得到一个只包含 ASCII 字符的字符串。
import java.util.Base64;
public class BinaryDataToString {
public static void main(String[] args) {
// 假设这是一个二进制文件(如图片)的字节数组
byte[] binaryData = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; // PNG 文件头
// 错误做法:直接转成 String,几乎一定会乱码
String wrongWay = new String(binaryData, StandardCharsets.UTF_8);
System.out.println("错误做法(二进制转String): " + wrongWay);
// 正确做法:使用 Base64 编码
String base64String = Base64.getEncoder().encodeToString(binaryData);
System.out.println("正确做法(二进制转Base64): " + base64String);
// 解码回来
byte[] decodedData = Base64.getDecoder().decode(base64String);
System.out.println("Base64 解码后的字节数组长度: " + decodedData.length);
}
}
总结与最佳实践
| 场景 | 推荐方法 | 关键点 |
|---|---|---|
单个 byte 转 String |
new String(new byte[]{b}, StandardCharsets.US_ASCII) |
单个 byte 通常没有意义,除非是 ASCII 字符。 |
byte[] 转 String (文本) |
new String(byteArray, StandardCharsets.UTF_8) |
必须指定编码。UTF-8 是现代应用的首选。 |
String 转 byte[] (文本) |
str.getBytes(StandardCharsets.UTF_8) |
必须指定编码,确保编码和解码一致。 |
byte[] 转 String (二进制) |
不要直接转换,使用 Base64.getEncoder().encodeToString() |
二进制数据转字符串是危险且无意义的,应使用 Base64 等安全编码。 |
黄金法则:
在处理
byte[]和String之间的转换时,始终明确地指定字符编码,如果不确定,使用StandardCharsets.UTF_8是最安全、最现代的选择。
