首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

深度解析 Java 字符編碼內部機制

     編輯:Java 相關知識

前言

Java 為實現國際化,內部使用 Unicode 字符集存儲字符。但 Unicode 僅是字符集,具體存儲需具體編碼方案(UTF-8、UTF-16 等)。許多開發者混淆 Unicode 與 UTF-8,導致對 Java 內部編碼產生誤解。本文通過實驗驗證 Java 真實的內部編碼格式。

實驗驗證

1. char 類型佔用空間

String name = "堂";
char c = name.charAt(0);  // 單字符

int low  = c & 0xff;        // 低位字節
int high = (c >> 8) & 0xff; // 高位字節
System.out.println(Integer.toHexString(high) + " " + Integer.toHexString(low));
// 輸出: 58 02  (僅 2 字節 = 16 位)

結論:Java char 固定 16 位,非 UTF-8(UTF-8 為變長編碼,中文通常 3 字節)。

2. 獲取真實 UTF-8 編碼

byte[] utf8 = name.getBytes("UTF-8");
printBytes(utf8);
// 輸出: e5 a0 82  length = 3  (3 字節,符合 UTF-8 中文編碼)

3. 嘗試 UTF-16

byte[] utf16 = name.getBytes("UTF-16");
printBytes(utf16);
// 輸出: fe ff 58 02  length = 4  (含 BOM 頭 2 字節)

去除 BOM 後低 16 位 58 02 與 char 內部值一致,說明內部編碼與 UTF-16 相關。

4. 驗證 UTF-16BE (Big Endian 無 BOM)

byte[] utf16be = name.getBytes("UTF-16BE");
printBytes(utf16be);
// 輸出: 58 02  length = 2  (完全匹配 char 內部值)

結論:Java 內部字符編碼為 UTF-16BE(大端序,無 BOM)。

輔助方法

public static void printBytes(byte[] bytes) {
    for (byte b : bytes) {
        System.out.print(Integer.toHexString(b & 0xff) + " ");
    }
    System.out.println(" length = " + bytes.length);
}

補充知識點

  • UTF-16LE:小端序編碼,字節序相反。
  • String.getBytes(charset) 會按指定編碼將內部 UTF-16BE 轉換為目標字節序列。
  • new String(bytes, charset) 為逆向操作:按編碼解碼字節數組為內部 UTF-16BE。
  • 理解內部編碼有助於正確處理 I/O、網絡傳輸、數據庫交互中的編碼轉換,避免「雙重編碼」或「編碼不匹配」導致的亂碼。

結語

Java 內部採用 UTF-16BE 固定 16 位編碼存儲字符,而非 UTF-8。掌握此本質,結合 getBytes() / String 构造器 進行顯式編碼轉換,是解決中文亂碼問題的關鍵基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved