杰瑞科技汇

Java字符串占几个字节?

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

Java字符串占几个字节?-图1
(图片来源网络,侵删)

下面我将从几个层面详细解释这个问题。

没有固定字节数

在 Java 中,String 对象本身是一个抽象的字符序列,它不直接关心字节,只有当你需要将 String 转换成字节数组(存储到文件、数据库或通过网络传输)时,字符编码 才会决定每个字符占用多少个字节。


字符串的内部表示 (UTF-16)

要了解 Java String 的内部存储方式,从 Java 9 开始,String 的内部表示是基于 UTF-16 的编码。

  • 每个 char 占用 2 个字节。
  • 一个 String 由一个 final char[] 数组构成。

示例:

Java字符串占几个字节?-图2
(图片来源网络,侵删)
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,推荐使用。

Java字符串占几个字节?-图3
(图片来源网络,侵删)

实践中的建议

  1. 始终明确指定编码:在任何涉及字符串与字节转换的场景下,都不要依赖默认编码,始终显式地传入 StandardCharsets.UTF_8 或其他你确定的编码。

    // 推荐
    byte[] bytes = myString.getBytes(StandardCharsets.UTF_8);
    // 不推荐
    byte[] bytes = myString.getBytes();
  2. 优先使用 UTF-8:UTF-8 是事实上的国际标准,它向后兼容 ASCII,对英文处理高效,同时又能完整支持全球所有语言,在 Web 开发、文件存储、数据库连接等所有现代场景下,都应默认使用 UTF-8。

  3. 如何获取 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 字节。

分享:
扫描分享到社交APP
上一篇
下一篇