String 是由字符组成的,而 byte[] 是由字节组成的,转换过程需要一种“字符编码”(Character Encoding)作为桥梁,将字符映射到字节。

如果不指定编码,Java 会使用平台默认的字符编码,这在不同操作系统或环境下可能导致不一致的结果,从而产生乱码。
核心方法:String.getBytes()
Java 的 String 类提供了 getBytes() 方法来完成这个转换。
不指定编码(不推荐)
String str = "Hello, 世界"; // 使用 JVM 默认的字符编码 byte[] bytes = str.getBytes(); // 在控制台打印字节数组 System.out.println(Arrays.toString(bytes)); // 输出可能因环境而异,例如在 UTF-8 环境下: // [72, 101, 108, 108, 111, 44, 32, -28, -72, -83, -27, -107, -116]
为什么不推荐?
因为如果这段代码在默认编码为 GBK 的 Windows 中文系统上运行,和在默认编码为 UTF-8 的 Linux 系统上运行,得到的 byte[] 内容会完全不同,当这个 byte[] 被传输或存储后,再用另一种编码去读取,就会得到乱码。
指定编码(强烈推荐)
这是最安全、最规范的做法,你应该始终明确地指定字符编码。

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class StringToByteExample {
public static void main(String[] args) {
String str = "Hello, 世界";
try {
// --- 1. 使用 try-catch 块(传统方式)---
// 指定使用 UTF-8 编码
byte[] utf8Bytes = str.getBytes("UTF-8");
System.out.println("UTF-8 编码: " + Arrays.toString(utf8Bytes));
// 指定使用 GBK 编码
byte[] gbkBytes = str.getBytes("GBK");
System.out.println("GBK 编码: " + Arrays.toString(gbkBytes));
// 如果编码不存在,会抛出 UnsupportedEncodingException
// byte[] invalidBytes = str.getBytes("INVALID_ENCODING");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// --- 2. 使用 StandardCharsets(Java 7+ 推荐方式)---
// 这种方式更简洁,无需 try-catch,因为 StandardCharsets 中的编码都是 guaranteed to be supported.
byte[] utf8BytesModern = str.getBytes(StandardCharsets.UTF_8);
System.out.println("StandardCharsets.UTF_8: " + Arrays.toString(utf8BytesModern));
byte[] gbkBytesModern = str.getBytes(StandardCharsets.ISO_8859_1); // ISO-8859-1 不支持中文
System.out.println("StandardCharsets.ISO_8859_1: " + Arrays.toString(gbkBytesModern));
}
}
输出示例:
UTF-8 编码: [72, 101, 108, 108, 111, 44, 32, -28, -72, -83, -27, -107, -116]
GBK 编码: [72, 101, 108, 108, 111, 44, 32, -42, -48, -50, -60, -29, -33, -68]
StandardCharsets.UTF_8: [72, 101, 108, 108, 111, 44, 32, -28, -72, -83, -27, -107, -116]
StandardCharsets.ISO_8859_1: [72, 101, 108, 108, 111, 44, 32, 63, 63]
从输出中可以看到,"世界"这两个汉字在 ISO-8859-1 编码下无法表示,被转换为了 ,这再次证明了选择正确编码的重要性。
常见字符编码
| 编码名称 | 描述 | 适用场景 |
|---|---|---|
| UTF-8 | 强烈推荐,变长编码,兼容 ASCII,可以表示全球所有字符,是互联网上最广泛使用的编码。 | Web 开发、文件存储、网络通信、API 接口等几乎所有现代场景。 |
| GBK | 中国国家标准编码,支持全部中文字符。 | 处理一些旧的、只针对中文简体的系统或文件时可能会用到。 |
| ISO-8859-1 (Latin-1) | 单字节编码,仅支持西欧语言。一个重要特性:它不会造成数据丢失,任何字节序列都可以被它正确解码。 | 常用作一种“安全”的中间编码,或者在不确定原始编码时,先用它来转换,避免数据损坏。 |
| UTF-16 | 定长编码(大部分字符占2字节),Java 内部就是使用 UTF-16 表示 String。 |
Windows 内部编码、Java 内部处理,一般不推荐在网络或文件中直接使用。 |
反向操作:byte[] 转 String
将 byte[] 转换回 String,同样需要指定编码,并且编码必须与当初转换时使用的编码一致,否则必然乱码。
import java.nio.charset.StandardCharsets;
public class ByteToStringExample {
public static void main(String[] args) {
String originalStr = "Hello, 世界";
byte[] bytes = originalStr.getBytes(StandardCharsets.UTF_8);
// 使用相同的编码(UTF-8)进行转换
String restoredStr = new String(bytes, StandardCharsets.UTF_8);
System.out.println("还原后的字符串: " + restoredStr); // 输出: Hello, 世界
// 使用错误的编码(ISO-8859-1)进行转换
String corruptedStr = new String(bytes, StandardCharsets.ISO_8859_1);
System.out.println("乱码字符串: " + corruptedStr); // 输出: Hello, ä¸çï¼
}
}
总结与最佳实践
- 始终指定编码:永远不要依赖平台的默认编码,在进行
String和byte[]互转时,必须明确指定字符集。 - 优先使用
StandardCharsets:如果你使用的是 Java 7 或更高版本,StandardCharsets.UTF_8是首选,它避免了UnsupportedEncodingException异常,代码更简洁、更安全。 - 统一编码:在项目内部、服务端与客户端之间、文件读写等场景下,应统一使用一种编码(强烈推荐 UTF-8),以避免乱码问题。
- 选择正确的编码:
- 通用场景:用
StandardCharsets.UTF_8。 - 处理旧中文系统:可能需要用
"GBK"。 - 作为安全转换:有时会用
StandardCharsets.ISO_8859_1,因为它能保证字节不丢失。
- 通用场景:用
推荐的写法:

// String -> byte[] String myString = "你好"; byte[] myBytes = myString.getBytes(StandardCharsets.UTF_8); // byte[] -> String String myStringAgain = new String(myBytes, StandardCharsets.UTF_8);
