計算機本質上只處理數字,字符集定義了數字到字符的映射規則。早期 ASCII 使用 7 位編碼(如 H=72),而 EBCDIC 則完全不同(H=200)。Java 採用 Unicode 作為內部表示,通過 java.nio.charset 包實現不同字符集間的雙向轉換。
// 1. 獲取字符集實例
Charset utf8 = Charset.forName("UTF-8");
// 2. 創建編解碼器
CharsetDecoder decoder = utf8.newDecoder();
CharsetEncoder encoder = utf8.newEncoder();
// 3. 執行轉換
ByteBuffer byteBuf = ByteBuffer.wrap(new byte[] {72, 101, 108, 108, 111});
CharBuffer charBuf = decoder.decode(byteBuf); // 字節 → 字符
ByteBuffer encoded = encoder.encode(charBuf); // 字符 → 字節
每個 Java 實現必須支持:
| 名稱 | 說明 |
|---|---|
| US-ASCII | 7 位 ASCII |
| ISO-8859-1 | ISO Latin-1 |
| UTF-8 | 8 位變長編碼 |
| UTF-16BE/LE | 16 位固定長度,大/小端序 |
| UTF-16 | 帶 BOM 標記的 16 位編碼 |
import java.nio.*;
import java.nio.charset.*;
import java.util.Arrays;
public class CharsetConversionDemo {
public static void main(String[] args) {
// 列出所有可用字符集
System.out.println("可用字符集: " + Charset.availableCharsets().keySet());
// ASCII "Hello" 字節數組
byte[] asciiBytes = {72, 101, 108, 108, 111};
ByteBuffer src = ByteBuffer.wrap(asciiBytes);
try {
// 解碼為字符
CharsetDecoder decoder = Charset.forName("US-ASCII").newDecoder();
CharBuffer chars = decoder.decode(src);
System.out.println("解碼結果: " + chars); // Hello
// 編碼為 UTF-16LE
CharsetEncoder encoder = Charset.forName("UTF-16LE").newEncoder();
ByteBuffer utf16 = encoder.encode(chars);
// 輸出字節值
byte[] result = utf16.array();
for (int i = 0; i < result.length; i++) {
System.out.printf("%d: %d%n", i, result[i]);
}
} catch (CharacterCodingException e) {
e.printStackTrace();
}
}
}
除手動編解碼外,可直接在流構造函數指定字符集:
// 自動處理編碼轉換
InputStreamReader reader = new InputStreamReader(inputStream, "GBK");
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
若需支持非標準字符集,可實現 java.nio.charset.spi.CharsetProvider 並通過 SPI 機制註冊。