String->byte[]: 将字符串中的字符按照指定的编码规则转换成字节。byte[]->String: 将一串字节按照指定的编码规则重新组合成字符。
如果编码规则不一致,就会出现乱码( 或乱七八糟的字符)。

(图片来源网络,侵删)
核心概念:字符编码
计算机只认识 0 和 1,为了存储和传输文本,我们需要将字符(如 'A', '中')映射成数字,再将数字转换成字节,这个映射规则就是字符编码。
- ASCII: 最早期的编码,仅支持英文字符,1个字符占1个字节。
- ISO-8859-1: 支持西欧语言,1个字符占1个字节。
- GBK / GB2312: 中国国家标准编码,支持大部分中文字符,1个字符通常占2个字节。
- UTF-8: 目前互联网上最通用的编码,它是一种可变长度的编码,英文字符占1个字节,中文字符通常占3个字节,生僻字符可能占更多。强烈推荐在所有新项目中使用 UTF-8。
- UTF-16: Java 内部使用的编码,固定使用2个或4个字节表示一个字符。
关键点:在转换时,必须明确使用哪种编码,如果不指定,Java 会使用系统的默认编码,这在不同环境下(如 Windows/Linux/macOS)可能会导致不一致的结果。
String 转 byte[]
使用 String 类的 getBytes() 方法。
推荐方式:显式指定编码
这是最安全、最推荐的做法,可以确保代码在任何环境下行为一致。

(图片来源网络,侵删)
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets; // Java 7+ 推荐使用这个类
public class StringToBytes {
public static void main(String[] args) {
String str = "Hello, 世界!";
// --- 推荐方式:使用 StandardCharsets (Java 7+) ---
// StandardCharsets 提供了预定义的常量,无需处理异常
byte[] utf8Bytes = str.getBytes(StandardCharsets.UTF_8);
System.out.println("UTF-8 编码的字节数组: " + java.util.Arrays.toString(utf8Bytes));
// 也可以直接传入字符串名称
try {
byte[] gbkBytes = str.getBytes("GBK");
System.out.println("GBK 编码的字节数组: " + java.util.Arrays.toString(gbkBytes));
} catch (UnsupportedEncodingException e) {
System.err.println("不支持的编码: " + e.getMessage());
}
// --- 不推荐方式:使用平台默认编码 ---
// 这种方式在不同系统上可能产生不同的结果,不推荐
byte[] defaultBytes = str.getBytes();
System.out.println("默认编码的字节数组: " + java.util.Arrays.toString(defaultBytes));
}
}
输出示例:
UTF-8 编码的字节数组: [72, 101, 108, 108, 111, 44, 32, -28, -72, -83, -26, -107, -116, 33]
GBK 编码的字节数组: [72, 101, 108, 108, 111, 44, 32, -42, -48, -71, -6, 33]
默认编码的字节数组: [72, 101, 108, 108, 111, 44, 32, -28, -72, -83, -26, -107, -116, 33] // 在中文 Windows 系统上,默认通常是 GBK
注意:负数是因为 Java 的 byte 类型是 8 位有符号的,当最高位是 1 时,它会以补码形式表示。
byte[] 转 String
使用 String 的构造函数 String(byte[] bytes, Charset charset)。
推荐方式:显式指定编码
同样,这是最安全的方式。

(图片来源网络,侵删)
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class BytesToString {
public static void main(String[] args) {
byte[] utf8Bytes = {72, 101, 108, 108, 111, 44, 32, -28, -72, -83, -26, -107, -116, 33};
// --- 推荐方式:使用 StandardCharsets ---
String strFromUtf8 = new String(utf8Bytes, StandardCharsets.UTF_8);
System.out.println("从 UTF-8 字节数组解码的字符串: " + strFromUtf8);
// --- 演示乱码情况 ---
// 如果用错误的编码来解码,就会产生乱码
// 用 ISO-8859-1(单字节编码)去解码一个 UTF-8 编码的字节数组
String wrongStr = new String(utf8Bytes, java.nio.charset.StandardCharsets.ISO_8859_1);
System.out.println("用 ISO-8859-1 错误解码的字符串: " + wrongStr); // 输出: Hello, 世界!
// --- 不推荐方式:使用平台默认编码 ---
String strFromDefault = new String(utf8Bytes);
System.out.println("用默认编码解码的字符串: " + strFromDefault);
}
}
输出示例:
从 UTF-8 字节数组解码的字符串: Hello, 世界!
用 ISO-8859-1 错误解码的字符串: Hello, 世界! // 乱码
用默认编码解码的字符串: Hello, 世界! // 在中文 Windows 系统上,默认通常是 GBK,但这里恰好能正确解码
实用场景:Base64 编码转换
Base64 是一种将二进制数据(如 byte[])转换成纯文本字符串的编码方式,它不是一种字符编码,而是一种表示二进制数据的“文本化”方法,常用于在 URL、XML 或 JSON 中传输数据。
Java 8+ 提供了内置的 java.util.Base64 工具类。
byte[] -> Base64 String
import java.util.Base64;
public class BytesToBase64 {
public static void main(String[] args) {
String originalString = "Hello, Base64!";
byte[] bytesToEncode = originalString.getBytes(StandardCharsets.UTF_8);
// 编码
String base64EncodedString = Base64.getEncoder().encodeToString(bytesToEncode);
System.out.println("Base64 编码后的字符串: " + base64EncodedString);
// 也可以直接编码字节数组
byte[] base64EncodedBytes = Base64.getEncoder().encode(bytesToEncode);
System.out.println("Base64 编码后的字节数组: " + new String(base64EncodedBytes, StandardCharsets.UTF_8));
}
}
输出:
Base64 编码后的字符串: SGVsbG8sIEJhc2U2NCU=
Base64 编码后的字节数组: SGVsbG8sIEJhc2U2NCU=
Base64 String -> byte[]
import java.util.Base64;
public class Base64ToBytes {
public static void main(String[] args) {
String base64EncodedString = "SGVsbG8sIEJhc2U2NCU=";
// 解码
byte[] decodedBytes = Base64.getDecoder().decode(base64EncodedString);
String decodedString = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println("Base64 解码后的字符串: " + decodedString);
}
}
输出:
Base64 解码后的字符串: Hello, Base64!
总结与最佳实践
| 转换方向 | 推荐方法 | 说明 |
|---|---|---|
String -> byte[] |
str.getBytes(StandardCharsets.UTF_8) |
始终显式指定编码。StandardCharsets 是 Java 7+ 引入的,是类型安全的,无需处理 UnsupportedEncodingException。 |
byte[] -> String |
new String(bytes, StandardCharsets.UTF_8) |
始终显式指定编码,确保解码时使用的编码与当初编码时使用的编码一致,否则会产生乱码。 |
| 二进制数据转文本 | Base64.getEncoder().encodeToString(bytes) |
当需要将二进制数据(如图片、文件内容)嵌入到文本协议(如 JSON, XML, HTTP 请求体)时使用。 |
| 文本转回二进制数据 | `Base64.getDecoder().decode(str |
