1. 概述

在Java中处理字符串(String)时,我们经常需要将其编码为特定的字符集(charset)。

本文将通过实际示例,介绍如何将字符串编码为 UTF-8 的几种常用方式。

如果你对字符编码底层机制感兴趣,可以参考我们的《Java字符编码指南》。

✅ 提醒:本文重点是“编码为UTF-8”,不是“判断是否为UTF-8”或“检测乱码”。


2. 问题背景

我们先通过一个实际例子,理解为什么需要显式编码为 UTF-8。

考虑这句德语字符串:

String germanString = "Entwickeln Sie mit Vergnügen";
byte[] germanBytes = germanString.getBytes();

String asciiEncodedString = new String(germanBytes, StandardCharsets.US_ASCII);

assertNotEquals(asciiEncodedString, germanString);

执行后,asciiEncodedString 输出为 "Entwickeln Sie mit Vergn?gen" —— 原因是 ü 不是 ASCII 字符,在 US-ASCII 编码下会被替换为 ?,导致信息丢失。

⚠️ 这就是典型的“乱码踩坑”:看似只是转个字节流,结果非英文字符全变成问号。

但如果是纯英文字符串,ASCII 和 UTF-8 是兼容的:

String englishString = "Develop with pleasure";
byte[] englishBytes = englishString.getBytes();

String asciiEncondedEnglishString = new String(englishBytes, StandardCharsets.US_ASCII);

assertEquals(asciiEncondedEnglishString, englishString);

✅ 因为 UTF-8 是 ASCII 的超集,所有 ASCII 字符在 UTF-8 中编码一致。

所以,要安全处理多语言文本,统一使用 UTF-8 是最佳实践


3. 使用 Java 核心类库编码

Java 中的 String 是不可变的,且内部以 UTF-16 存储,无法直接修改其编码格式

我们能做的,是将其转换为指定编码的字节数组,再用该字节数组重建字符串。

步骤:

  1. 调用 String.getBytes(Charset) 获取 UTF-8 字节
  2. 使用 new String(byte[], Charset) 重建字符串
String rawString = "Entwickeln Sie mit Vergnügen";
byte[] bytes = rawString.getBytes(StandardCharsets.UTF_8);

String utf8EncodedString = new String(bytes, StandardCharsets.UTF_8);

assertEquals(rawString, utf8EncodedString);

✅ 简单粗暴,无需额外依赖,推荐日常使用。

⚠️ 注意:不要使用无参 getBytes(),它使用平台默认编码(如 Windows 是 Cp1252),极易引发跨平台乱码问题。


4. 使用 Java 7+ 的 StandardCharsets

从 Java 7 开始,java.nio.charset.StandardCharsets 提供了标准字符集常量,比硬编码字符串更安全。

我们可以借助 Charset.encode()Charset.decode() 来完成编码转换:

String rawString = "Entwickeln Sie mit Vergnügen";
ByteBuffer buffer = StandardCharsets.UTF_8.encode(rawString); 

String utf8EncodedString = StandardCharsets.UTF_8.decode(buffer).toString();

assertEquals(rawString, utf8EncodedString);

优势:

  • ✅ 类型安全,避免拼写错误(如 "UTF8" vs "UTF-8"
  • ✅ 无需捕获异常,StandardCharsets 的常量不会为 null
  • ✅ 适用于 NIO 场景,与 ByteBuffer 集成良好

⚠️ 注意:encode() 返回的是 ByteBuffer,操作后 position 会改变,如需重复使用记得 rewind()


5. 使用 Apache Commons Codec

如果你的项目已经引入了 Apache Commons Codec,可以用它提供的工具类简化操作。

5.1 添加 Maven 依赖

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.14</version>
</dependency>

5.2 使用 StringUtils 工具类

StringUtils 提供了开箱即用的 UTF-8 编解码方法:

String rawString = "Entwickeln Sie mit Vergnügen"; 
byte[] bytes = StringUtils.getBytesUtf8(rawString);
 
String utf8EncodedString = StringUtils.newStringUtf8(bytes);

assertEquals(rawString, utf8EncodedString);

优点:

  • ✅ 方法命名清晰,getBytesUtf8 / newStringUtf8 一看就懂
  • ✅ 空值安全(传入 null 不会抛异常)
  • ✅ 代码更简洁,适合频繁编解码场景

❌ 缺点:引入额外依赖,纯 JDK 项目可不考虑。


6. 总结

方法 是否需要依赖 推荐场景
String.getBytes(StandardCharsets.UTF_8) ❌ 不需要 ✅ 日常开发首选
StandardCharsets.UTF_8.encode() ❌ 不需要 ✅ NIO 场景或需精确控制 ByteBuffer
StringUtils.getBytesUtf8() ✅ 需要 commons-codec ✅ 已使用 Commons 的项目

🔚 最终建议:**优先使用 StandardCharsets.UTF_8 + getBytes()**,简单、安全、无依赖。

所有示例代码已上传至 GitHub:https://github.com/baeldung/tutorials/tree/master/core-java-modules/core-java-string-operations-2


原始标题:Encode a String to UTF-8 in Java