这是一个非常常见且重要的问题,但答案比一个简单的数字要复杂得多。一个 Java 字符串的字节数取决于它所使用的字符编码(Character Encoding)。

下面我将从几个层面详细解释这个问题。
没有固定字节数
在 Java 中,String 对象本身是一个抽象的字符序列,它不直接关心字节,只有当你需要将 String 转换成字节数组(存储到文件、数据库或通过网络传输)时,字符编码 才会决定每个字符占用多少个字节。
字符串的内部表示 (UTF-16)
要了解 Java String 的内部存储方式,从 Java 9 开始,String 的内部表示是基于 UTF-16 的编码。
- 每个
char占用 2 个字节。 - 一个
String由一个final char[]数组构成。
示例:

String str = "A";
// 内部存储: char[] = {'A'}
// 'A' 是一个基本多文种平面 (BMP) 字符,占用 1 个 char,即 2 个字节。
String str2 = "中";
// 内部存储: char[] = {'中'}
// '中' 是一个 BMP 字符,也占用 1 个 char,即 2 个字节。
String str3 = "😊";
// 内部存储: char[] = {'\uD83D', '\uDE00'}
// '😊' 是一个辅助平面字符(需要两个 char 表示,称为代理对),占用 2 个 char,即 4 个字节。
重要提示: 虽然内部是 UTF-16,但你不能直接用 str.getBytes().length 来获取字符串的字节数,因为这个方法会使用平台的默认字符编码,这通常不是你想要的结果,并且在不同的操作系统上(如 Windows vs. Linux)可能会得到不同的答案。
关键:外部编码决定字节数
当你需要将字符串转换为字节数组时,必须指定一个字符编码,以下是几种最常见的编码及其对字节数的影响。
场景:计算字符串 "Hello, 世界" 的字节数
这个字符串包含 7 个英文字符和 2 个中文字符。
| 字符编码 | 描述 | 每个英文字符 (如 'H') | 每个中文字符 (如 '世') | 字符串 "Hello, 世界" 总字节数 |
|---|---|---|---|---|
| UTF-8 | 目前最通用、最推荐的编码,可变长度,对英文非常友好。 | 1 字节 | 3 字节 | 5*1 + 1*1 + 2*3 = 5 + 1 + 6 = 12 字节 |
| GBK / GB2312 | 中文环境下常用的编码,对英文和中文都是固定长度。 | 1 字节 | 2 字节 | 5*1 + 1*1 + 2*2 = 5 + 1 + 4 = 10 字节 |
| ISO-8859-1 | 单字节编码,无法表示中文字符。 | 1 字节 | 无法表示,会变成 ? | 7*1 = 7 字节(信息会丢失) |
| UTF-16 | Java String 的内部编码,固定长度(辅助平面字符除外)。 |
2 字节 | 2 字节 | 7*2 = 14 字节 |
Java 代码示例
public class StringByteSize {
public static void main(String[] args) {
String str = "Hello, 世界";
// 1. 使用 UTF-8 编码 (推荐)
byte[] utf8Bytes = str.getBytes(StandardCharsets.UTF_8);
System.out.println("UTF-8 字节数: " + utf8Bytes.length); // 输出: 12
// 2. 使用 GBK 编码 (常见于中文环境)
byte[] gbkBytes = str.getBytes("GBK"); // 需要处理 UnsupportedEncodingException
System.out.println("GBK 字节数: " + gbkBytes.length); // 输出: 10
// 3. 使用 ISO-8859-1 编码 (不推荐,会丢失中文信息)
byte[] iso88591Bytes = str.getBytes(StandardCharsets.ISO_8859_1);
System.out.println("ISO-8859-1 字节数: " + iso88591Bytes.length); // 输出: 7
// 4. 使用 UTF-16 编码 (Java内部编码)
byte[] utf16Bytes = str.getBytes(StandardCharsets.UTF_16);
System.out.println("UTF-16 字节数: " + utf16Bytes.length); // 输出: 16 (注意:这里有个2字节的BOM头)
// 5. 错误示范:使用平台默认编码
// 在中文Windows上可能是GBK,在Linux上可能是UTF-8,结果不可预测!
byte[] defaultBytes = str.getBytes();
System.out.println("默认编码 字节数: " + defaultBytes.length);
}
}
注意:
StandardCharsets是 Java 7 引入的枚举,可以避免UnsupportedEncodingException,推荐使用。(图片来源网络,侵删)
实践中的建议
-
始终明确指定编码:在任何涉及字符串与字节转换的场景下,都不要依赖默认编码,始终显式地传入
StandardCharsets.UTF_8或其他你确定的编码。// 推荐 byte[] bytes = myString.getBytes(StandardCharsets.UTF_8); // 不推荐 byte[] bytes = myString.getBytes();
-
优先使用 UTF-8:UTF-8 是事实上的国际标准,它向后兼容 ASCII,对英文处理高效,同时又能完整支持全球所有语言,在 Web 开发、文件存储、数据库连接等所有现代场景下,都应默认使用 UTF-8。
-
如何获取
String在特定编码下的字节数? 这是最常见的需求,方法就是上面代码中展示的:String text = "你好,Java"; int byteCount = text.getBytes(StandardCharsets.UTF_8).length; System.out.println("UTF-8 编码下的字节数: " + byteCount);
| 问题 | 答案 |
|---|---|
Java String 内部是多少字节? |
基于 UTF-16 编码,一个基本字符(char)占 2 个字节。 |
| 一个字符串对象占多少内存? | 这很复杂,不仅包括字符数组,还包括对象头、数组长度等,通常远大于字节数。String 对象本身是只读的,所以内存占用是固定的。 |
| 如何计算一个字符串的字节数? | 必须指定字符编码,使用 myString.getBytes("charsetName").length 来计算。 |
| 应该用什么编码? | 强烈推荐使用 UTF-8,除非你对接的旧系统强制要求使用 GBK 等其他编码。 |
当有人再问“Java string 几个字节?”时,最准确的回答是:“这取决于你用什么编码把它转成字节,在 UTF-8 编码下,一个英文字符是 1 字节,一个中文字符通常是 3 字节。”

