中文亂碼本質是「編碼與解碼格式不一致」。本文從微觀流程切入,完整梳理 Java 源碼保存 → javac 編譯 → Class 字節碼 → JVM 載入 → Console/Servlet/DB 三大運行場景的編解碼轉換鏈路,並給出 I/O、記憶體、資料庫、Java Web 四大場景的最佳實踐代碼與避坑指南。
.java。file.encoding 或 -encoding 參數,將源碼轉為 Unicode 存入 .class 常量池。.class,字符串常量在記憶體以 UTF-16 (char[]) 形式存在。System.in/out 按 file.encoding 轉碼。characterEncoding=utf8。String s = "我是 cm";
// 編碼:String → byte[]
byte[] utf8 = s.getBytes("UTF-8"); // 指定編碼
byte[] gbk = s.getBytes("GBK");
byte[] iso = s.getBytes("ISO-8859-1"); // 中文變 ??
// 解碼:byte[] → String
String s1 = new String(utf8, "UTF-8"); // 正確
String s2 = new String(utf8, "GBK"); // 亂碼
String s3 = new String(utf8); // 平台預設編碼,風險大
字符 UTF-8 GBK ISO-8859-1
我 E6 88 91 CE D2 3F (?)
是 E6 98 AF CA C7 3F (?)
空格 20 20 20
c 63 63 63
m 6D 6D 6D
// 讀取 UTF-8 文件
try (InputStream is = new FileInputStream("test.txt");
Reader r = new InputStreamReader(is, StandardCharsets.UTF_8)) {
char[] buf = new char[1024];
int len; while ((len = r.read(buf)) != -1) { /* 處理 */ }
}
// 寫入 UTF-8 文件
try (OutputStream os = new FileOutputStream("out.txt");
Writer w = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
w.write("中文內容");
}
// 1. 請求過濾器統一設定
request.setCharacterEncoding("UTF-8");
// 2. 回應設定
response.setContentType("text/html;charset=UTF-8");
// 3. Tomcat server.xml Connector 加上 URIEncoding="UTF-8"
// 4. JSP 頁面指令 <%@ page pageEncoding="UTF-8" %>
// 5. JDBC URL: jdbc:mysql://...?characterEncoding=utf8&useSSL=false
掌握「編碼必須成對、全鏈路統一」原則,亂碼問題將不再是噩夢。