杰瑞科技汇

Java字符串如何转为byte数组?

核心概念:为什么需要编码?

计算机只认识 0 和 1(字节),字符串是 char 类型的序列,而 char 在 Java 中是 16 位的 Unicode 字符,为了将字符串存储到文件、在网络中传输或存入数据库,必须将这些 char 转换为一系列的字节。

Java字符串如何转为byte数组?-图1
(图片来源网络,侵删)

字符编码就是一套规则,规定了如何将字符映射到字节序列,最常用的编码是 UTF-8


使用 String.getBytes()(不推荐,除非你明确知道后果)

这是最直接的方法,但它依赖于平台默认的字符编码

public class StringToByteExample {
    public static void main(String[] args) {
        String str = "你好,Java!";
        // 使用平台默认的字符编码进行转换
        // 在中文 Windows 系统上,默认可能是 GBK
        // 在 Linux 或 macOS 上,默认通常是 UTF-8
        byte[] bytes = str.getBytes();
        System.out.println("原始字符串: " + str);
        System.out.println("转换后的字节数组: " + Arrays.toString(bytes));
    }
}

为什么不推荐? 因为“平台默认编码”是不可靠的,你的代码在你的电脑上运行正常,但部署到另一台使用不同默认编码的服务器上时,就可能产生乱码,这会导致难以排查的“间歇性”bug。


使用 String.getBytes(StandardCharsets.UTF_8)(推荐,最常用)

这是最推荐、最安全的方式,显式地指定使用 UTF-8 编码,可以确保你的代码在任何平台上行为一致,避免乱码问题。

Java字符串如何转为byte数组?-图2
(图片来源网络,侵删)

StandardCharsets 是 Java 7 引入的一个枚举类,它预定义了几个最常用的字符集常量(UTF_8, ISO_8859_1, US_ASCII),使用它比直接传入字符串(如 "UTF-8")更高效、更安全。

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class StringToByteRecommended {
    public static void main(String[] args) {
        String str = "你好,Java!";
        // 强制使用 UTF-8 编码进行转换
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        System.out.println("原始字符串: " + str);
        System.out.println("使用 UTF-8 编码转换后的字节数组: " + Arrays.toString(bytes));
    }
}

输出示例:

原始字符串: 你好,Java!
使用 UTF-8 编码转换后的字节数组: [-60, -29, -70, -61, -43, -48, -50, -68, -77, -25, -68, -68, -103]

这个输出是跨平台一致的。


使用 String.getBytes(String charsetName)(需要处理异常)

如果你需要使用非标准的字符集(如 GBK, ISO-8859-1),可以使用这个重载方法,但它会抛出 UnsupportedEncodingException 异常,因此必须用 try-catch 包裹。

Java字符串如何转为byte数组?-图3
(图片来源网络,侵删)
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class StringToByteWithCharset {
    public static void main(String[] args) {
        String str = "你好,Java!";
        try {
            // 使用 GBK 编码进行转换
            byte[] gbkBytes = str.getBytes("GBK");
            System.out.println("使用 GBK 编码转换后的字节数组: " + Arrays.toString(gbkBytes));
            // 使用 ISO-8859-1 编码(仅支持 ASCII 字符,中文会乱码)
            byte[] isoBytes = str.getBytes("ISO-8859-1");
            System.out.println("使用 ISO-8859-1 编码转换后的字节数组: " + Arrays.toString(isoBytes));
        } catch (UnsupportedEncodingException e) {
            System.err.println("不支持的字符集编码");
            e.printStackTrace();
        }
    }
}

输出示例:

使用 GBK 编码转换后的字节数组: [-60, -29, -70, -61, -43, -48, -50, -68, -77, -25, -68, -68, -103]
使用 ISO-8859-1 编码转换后的字节数组: [63, 63, 63, 63, 63, 74, 97, 118, 97, 33]

注意,使用 ISO-8859-1 时,中文字符无法表示,被替换为了 。


反向操作:byte[] 转 String

将字节数组转换回字符串时,同样必须使用相同的编码,否则会乱码。

import java.nio.charset.StandardCharsets;
public class ByteToStringExample {
    public static void main(String[] args) {
        String originalStr = "Hello, 世界!";
        // 1. 字符串 -> byte[] (使用 UTF-8)
        byte[] bytes = originalStr.getBytes(StandardCharsets.UTF_8);
        System.out.println("原始字符串: " + originalStr);
        System.out.println("字节数组: " + Arrays.toString(bytes));
        // 2. byte[] -> 字符串 (必须使用相同的 UTF-8 编码)
        String decodedStr = new String(bytes, StandardCharsets.UTF_8);
        System.out.println("解码后的字符串: " + decodedStr);
        // 3. 错误示范:使用了错误的编码
        String wrongStr = new String(bytes, StandardCharsets.ISO_8859_1);
        System.out.println("使用错误编码解码后的字符串: " + wrongStr); // 会乱码
    }
}

输出:

原始字符串: Hello, 世界!
字节数组: [72, 101, 108, 108, 111, 44, 32, -28, -72, -83, -27, -101, -67, 33]
解码后的字符串: Hello, 世界!
使用错误编码解码后的字符串: Hello, 世界!

可以看到,使用错误的编码解码后,字符串变得不可读。


总结与最佳实践

方法 描述 优点 缺点 推荐度
str.getBytes() 使用平台默认编码 简单 不可靠,跨平台时可能乱码 ⭐☆☆☆☆ (不推荐)
str.getBytes(StandardCharsets.UTF_8) 使用指定的 UTF-8 编码 可靠、高效、跨平台一致 ⭐⭐⭐⭐⭐ (强烈推荐)
str.getBytes("GBK") 使用指定的字符集(如 GBK) 灵活,可用于处理旧系统数据 需要处理 UnsupportedEncodingException ⭐⭐⭐☆☆ (特定场景下使用)

核心原则:

  1. 优先使用 StandardCharsets.UTF_8:除非你有特殊需求(需要与一个只支持 GBK 的旧系统交互),否则总是使用 StandardCharsets.UTF_8,这是现代软件开发的事实标准。
  2. 编码和解码必须一致:将字符串转为字节时使用的编码,必须与将字节转回字符串时使用的编码完全相同。
  3. 避免平台默认编码:永远不要依赖 str.getBytes() 的默认行为,因为它会让你的代码变得脆弱和不可预测。
分享:
扫描分享到社交APP
上一篇
下一篇