java.lang.String.getBytes(String charsetName) 是 Java 處理字元編碼轉換的核心方法之一。本文詳細說明方法簽名、參數約束、返回值特性、異常處理,並提供完整可執行範例。
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
| 參數 | 類型 | 說明 | 備註 |
|---|---|---|---|
| charsetName | String | 支援的字元集名稱 | 大小寫不敏感,推薦使用 StandardCharsets 常量 |
常用字元集名稱:
UTF-8 / UTF8 - 通用 Unicode 編碼GBK / CP936 - 中文 Windows 預設GB2312 / EUC_CN - 簡體中文舊標準ISO-8859-1 / Latin-1 - 單字節西歐語言US-ASCII - 7 位元 ASCIIUTF-16BE / UTF-16LE - 固定大小端序byte[]UnsupportedEncodingException:指定的字元集不被當前 JRE 支援package com.example.stringdemo;
import java.nio.charset.StandardCharsets;
import java.io.UnsupportedEncodingException;
public class StringGetBytesDemo {
public static void main(String[] args) {
// 測試字串:包含 ASCII、中文、特殊符號
String str = "Hello 世界! $@#";
System.out.println("原始字串: " + str);
System.out.println("字串長度 (char 數): " + str.length());
System.out.println();
// 1. UTF-8 編碼 (推薦標準)
demoEncoding(str, "UTF-8", StandardCharsets.UTF_8);
// 2. GBK 編碼 (中文環境常用)
demoEncoding(str, "GBK", null);
// 3. ISO-8859-1 編碼 (單字節,中文會丟失)
demoEncoding(str, "ISO-8859-1", StandardCharsets.ISO_8859_1);
// 4. 展示無參版本 (使用平台預設編碼,不推薦生產使用)
System.out.println("=== 無參版本 getBytes() ===");
byte[] defaultBytes = str.getBytes();
System.out.println("平台預設編碼: " + System.getProperty("file.encoding"));
printBytes(defaultBytes);
}
private static void demoEncoding(String str, String charsetName, java.nio.charset.Charset charset) {
System.out.println("=== " + charsetName + " 編碼 ===");
try {
byte[] bytes = (charset != null) ? str.getBytes(charset) : str.getBytes(charsetName);
System.out.println("位元組長度: " + bytes.length);
printBytes(bytes);
// 反向解碼驗證
String decoded = new String(bytes, charsetName);
System.out.println("解碼還原: " + decoded);
System.out.println("是否一致: " + str.equals(decoded));
} catch (UnsupportedEncodingException e) {
System.err.println("不支援的字元集: " + charsetName);
e.printStackTrace();
}
System.out.println();
}
private static void printBytes(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
// 以無符號十六進制顯示 (0x00-0xFF)
sb.append(String.format("0x%02X ", bytes[i] & 0xFF));
// 每 8 個位元組換行
if ((i + 1) % 8 == 0) sb.append("\n");
}
System.out.println("位元組內容: " + sb.toString().trim());
}
}
原始字串: Hello 世界! $@#
字串長度 (char 數): 13
=== UTF-8 編碼 ===
位元組長度: 17
位元組內容: 0x48 0x65 0x6C 0x6C 0x6F 0x20 0xE4 0xB8 0x96 0xE7 0x95 0x8C 0x21 0x20 0x24 0x40 0x23
解碼還原: Hello 世界! $@#
是否一致: true
=== GBK 編碼 ===
位元組長度: 13
位元組內容: 0x48 0x65 0x6C 0x6C 0x6F 0x20 0xCA 0xC0 0xBD 0xE7 0x21 0x20 0x24 0x40 0x23
解碼還原: Hello 世界! $@#
是否一致: true
=== ISO-8859-1 編碼 ===
位元組長度: 13
位元組內容: 0x48 0x65 0x6C 0x6C 0x6F 0x20 0x3F 0x3F 0x21 0x20 0x24 0x40 0x23
解碼還原: Hello ??! $@#
是否一致: false
關鍵觀察:
0x3F (問號 ?),導致資訊永久遺失import java.nio.charset.StandardCharsets;
byte[] bytes = str.getBytes(StandardCharsets.UTF_8); // 無需 try-catch,編譯期安全
str.getBytes() 依賴 file.encoding 系統屬性,跨平台部署極易出錯CharsetEncoder 串流式處理,避免記憶體峰值CharsetEncoder 實例,減少物件創建| 方法 | 說明 | 推薦度 |
|---|---|---|
getBytes(Charset charset) | JDK 1.6+,傳入 Charset 物件,無受檢異常 | ⭐⭐⭐⭐⭐ |
getBytes(String charsetName) | 傳入字元集名稱字串,拋出 UnsupportedEncodingException | ⭐⭐⭐ |
getBytes() | 無參,使用平台預設編碼 | ⭐ (僅除錯用) |
getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) | JDK 1.1 遺留方法,已棄用,不支援補字元 | ❌ |
掌握 getBytes() 正確用法,是解決 Java 編碼問題的基石。建議專案統一制定編碼規範,Code Review 時重點檢查字串與位元組轉換處是否顯式指定字元集。