Java 內部用 UTF-16(Unicode),I/O 時按 file.encoding 系統屬性轉碼。中文亂碼本質是讀取時編碼 ≠ 寫入時編碼,或顯示字體不支持字符集。
// 讀取:指定源編碼 → 內部 Unicode
String str = new String(bytes, "GBK"); // 或 ISO-8859-1, UTF-8
// 寫出:Unicode → 指定目標編碼
byte[] out = str.getBytes("UTF-8");
常用編碼:GBK(兼容 GB2312,推薦)、UTF-8(國際化首選)、ISO-8859-1(單字節,可作透明傳輸)。
<%@ page contentType="text/html;charset=GBK" pageEncoding="GBK" %>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
javac -encoding GBK *.java
// 獲取參數
String param = new String(request.getParameter("p").getBytes("ISO-8859-1"), "GBK");
// 輸出
response.setContentType("text/html;charset=GBK");
out.write(new String("中文".getBytes("GBK"), "ISO-8859-1"));
切勿混用:要麼全鏈路 GBK/UTF-8,要麼全鏈路 ISO-8859-1 + 手動轉碼,混用必亂。
多數 JDBC 驅動默認 ISO-8859-1。讀寫統一轉碼:
// 讀
String val = new String(rs.getBytes("col"), "GBK");
// 寫
ps.setBytes(1, "中文".getBytes("GBK")); // 或 setString 後驅動內部按連接屬性轉碼
驅動差異大(如 i-net UNA 免轉碼),上線前必測。
JDK 1.2+ Windows 上自動檢測系統字體,無需手動覆蓋 font.properties。若 Linux/舊 JDK 需配置,複製 font.properties.zh 為 font.properties 並確認字體文件存在。
現象:命令行 java 正常顯示中文,JBuilder/IDE 內運行(調用 javaw)亂碼。
原因:javaw 強制使用英文 Locale,忽略系統設置(Bug ID: 4629351,Sun 宣稱修復但實際未修)。
解決:VM 參數強制指定 Locale 與編碼:
-Dfile.encoding=GBK -Ddefault.client.encoding=GBK -Duser.language=zh -Duser.region=CN
JBuilder 配置:Project Properties → Run → VM Parameters 添加上述參數。
Content-Type 聲明編碼 = 實際輸出編碼。URIEncoding="UTF-8")。characterEncoding=GBK(或 UTF-8)。-Dfile.encoding=... 覆蓋 javaw 缺陷。亂碼不可怕,可怕的是鏈路不統一。建立團隊「編碼憲法」,全鏈路 UTF-8,工具鏈強制檢查,才是治本之道。