英文 Windows 2000 + 中文支援包、JBuilder 7 + JDK 1.3/1.4、JTextArea 顯示亂碼……這不僅是作者當年的真實經歷,更是無數 Java 開發者的共同記憶。本文將「編碼轉換原理」「字體配置」「JVM 參數調優」三大維度串聯,給出經得起生產環境驗證的解決方案。
| 層面 | 說明 |
|---|---|
| Java 內部 | 統一使用 UTF-16 (Unicode) 表示 char/String |
| I/O 邊界 | Reader/Writer 依 file.encoding 轉碼;InputStream/OutputStream 處理原始位元組 |
| 常用編碼 | UTF-8(推薦)、GBK(兼容 GB2312)、ISO-8859-1(單位元組透傳) |
// 讀取 GBK 檔案
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(file), "GBK"))) { ... }
// 寫入 UTF-8
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))) { ... }
// 正確姿勢:位元組陣列 → 指定編碼 → String String correct = new String(bytes, StandardCharsets.UTF_8); // 反例:預設編碼會隨平台變化 String risky = new String(bytes); // 不要這樣寫
javac -encoding GBK *.java<%@ page contentType="text/html;charset=GBK" %>request.setCharacterEncoding("GBK")javac -encoding UTF-8 *.javacharset=UTF-8server.xml:<Connector URIEncoding="UTF-8" />?characterEncoding=UTF-8&useUnicode=true鐵律:嚴禁混用兩套方案,否則必亂碼。
// MySQL 8.0+ 驅動自動識別 UTF-8,僅需確保: // 1. 表/欄位 CHARSET=utf8mb4 // 2. 連線字串帶 useUnicode=true&characterEncoding=UTF-8 // 3. 程式碼端統一使用 UTF-8 字串,無需手動 getBytes 轉碼
font.properties 到邏輯字型font.properties 映射中文字型。Dialog、SansSerif、Monospaced),自動根據 file.encoding 落地到物理字型。javaw 的 Locale Bug (Bug ID 4629351)現象:同一 JDK,java -jar app.jar 正常顯示中文,javaw -jar app.jar 卻顯示方塊/亂碼。
根因:javaw(無主控台模式)在 Windows 上預設使用英文 Locale,導致 file.encoding 回退為 Cp1252,邏輯字型映射失效。
終極修復:啟動參數強制指定中文 Locale 與編碼:
javaw -Dfile.encoding=GBK -Ddefault.client.encoding=GBK \
-Duser.language=zh -Duser.region=CN -jar app.jar
在 JBuilder/IDE 中:Project Properties → Run → VM Parameters 填入上述參數即可。
-encoding UTF-8。URIEncoding="UTF-8",Filter 設定 request.setCharacterEncoding("UTF-8")。utf8mb4。-Dfile.encoding=UTF-8 -Duser.language=zh -Duser.region=CN。new String(bytes)、getBytes() 無參呼叫。遵循此清單,Java 中文問題將不再是「歷史遺留難題」,而是可控、可預期的工程配置項。