Base64 是將二進制數據編碼為 ASCII 字符串的標準算法,廣泛用於 HTTP 傳輸、數據庫存儲、Token 生成等場景。Java 提供了多種實現方式,本文對比三種主流方案:反射調用 JDK 內部類、Apache Commons Codec、Sun Misc 類,並給出演能與選型建議。
JDK 內部包含 com.sun.org.apache.xerces.internal.impl.dv.util.Base64,但屬於內部 API,版本間可能變動,且 Java 9+ 模組化後默認不可訪問。
public class Base64Reflect {
public static String encode(byte[] input) throws Exception {
Class> clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method method = clazz.getMethod("encode", byte[].class);
method.setAccessible(true);
return (String) method.invoke(null, input);
}
public static byte[] decode(String input) throws Exception {
Class> clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method method = clazz.getMethod("decode", String.class);
method.setAccessible(true);
return (byte[]) method.invoke(null, input);
}
}
缺點:依賴內部實現、反射開銷大、Java 9+ 需添加 --add-opens 參數、不可移植。
成熟、穩定、廣泛使用的第三方庫,提供流式處理、URL 安全變體、性能優化。
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.16.0</version> <!-- 查詢最新版 -->
</dependency>
import org.apache.commons.codec.binary.Base64;
public class Base64Codec {
// 編碼 byte[] -> String
public static String encode(byte[] bytes) {
return new String(Base64.encodeBase64(bytes), StandardCharsets.UTF_8);
}
// 編碼 byte[] -> byte[] (無字符串開銷)
public static byte[] encodeBytes(byte[] bytes) {
return Base64.encodeBase64(bytes);
}
// 解碼 String -> byte[]
public static byte[] decode(String str) {
return Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
}
// 解碼 byte[] -> byte[]
public static byte[] decode(byte[] bytes) {
return Base64.decodeBase64(bytes);
}
// URL 安全編碼 (替換 +/ 為 -_)
public static String encodeUrlSafe(byte[] bytes) {
return new String(Base64.encodeBase64URLSafe(bytes), StandardCharsets.UTF_8);
}
// 分塊編碼 (MIME 規範,每 76 字符換行)
public static String encodeChunked(byte[] bytes) {
return new String(Base64.encodeBase64Chunked(bytes), StandardCharsets.UTF_8);
}
}
try (InputStream in = new FileInputStream("large.bin");
OutputStream out = new FileOutputStream("large.b64")) {
Base64.encodeBase64(in, out); // 邊讀邊編碼,內存常數
}
sun.misc.BASE64Encoder / BASE64Decoder 是 JDK 早期提供的非標準實現,簡單但不推薦新項目使用。
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class Base64Sun {
private static final BASE64Encoder ENCODER = new BASE64Encoder();
private static final BASE64Decoder DECODER = new BASE64Decoder();
public static String encode(byte[] bytes) {
return ENCODER.encode(bytes);
}
public static byte[] decode(String str) {
try { return DECODER.decodeBuffer(str); }
catch (IOException e) { throw new RuntimeException(e); }
}
}
遷移提示:Java 9+ 需添加 --add-exports java.base/sun.misc=ALL-UNNAMED,長期規劃請遷移至標準 API。
Java 8 正式引入標準 Base64 支持,無需第三方依賴,性能優異,API 豐富。
import java.util.Base64;
public class Base64Standard {
private static final Base64.Encoder ENCODER = Base64.getEncoder();
private static final Base64.Decoder DECODER = Base64.getDecoder();
private static final Base64.Encoder URL_ENCODER = Base64.getUrlEncoder();
private static final Base64.Encoder MIME_ENCODER = Base64.getMimeEncoder();
public static String encode(byte[] bytes) {
return ENCODER.encodeToString(bytes);
}
public static byte[] encodeBytes(byte[] bytes) {
return ENCODER.encode(bytes);
}
public static byte[] decode(String str) {
return DECODER.decode(str);
}
public static byte[] decode(byte[] bytes) {
return DECODER.decode(bytes);
}
public static String encodeUrlSafe(byte[] bytes) {
return URL_ENCODER.encodeToString(bytes);
}
public static String encodeMime(byte[] bytes) {
return MIME_ENCODER.encodeToString(bytes);
}
// 流式編碼
public static void encodeStream(InputStream in, OutputStream out) throws IOException {
try (OutputStream encOut = ENCODER.wrap(out)) {
in.transferTo(encOut);
}
}
}
| 方案 | 優點 | 缺點 | 推薦場景 |
|---|---|---|---|
| java.util.Base64 (Java 8+) | 標準、零依賴、高性能、支持 URL/MIME/流式 | 需 Java 8+ | 所有新項目首選 |
| Commons Codec | 功能豐富、兼容舊版本、流式 API 成熟 | 引入依賴、體積較大 | Java 7 維護項目、需高級特性 |
| Sun Misc | 代碼極簡 | 非標準、Java 9+ 受限、性能一般 | 極簡腳本、Java 8 老舊項目快速修改 |
| 反射內部類 | 無額外依賴 | 極其脆弱、性能差、違反模組化 | 絕不推薦 |
java.util.Base64,單例復用 Encoder/Decoder,線程安全。StandardCharsets.UTF_8,避免平台默認編碼差異。Encoder.wrap(OutputStream) / Decoder.wrap(InputStream),避免全量載入內存。getUrlEncoder(),避免 + / = 需要再次編碼。getMimeEncoder() 自動換行。IllegalArgumentException,返回明確錯誤信息而非拋出堆棧。Base64 編解碼看似簡單,選對工具、用好流式、注意編碼細節,才能構建健壯高效的系統。