class 檔案常數池採 Modified UTF-8。sun.io.ByteToCharConverter、CharToByteConverter(內部實作,建議使用標準 InputStreamReader/OutputStreamWriter)。以「你」字為例:Big5/GBK = 0xC4E3,Unicode = 0x4F60。
// 位元組 → Char (解碼)
byte[] b = {(byte)0xC4, (byte)0xE3};
String s = new String(b, "GBK"); // 正確得到 "你"
String s2 = new String(b, "8859_1"); // 錯誤得到兩個雜湊字元
// Char → 位元組 (編碼)
char[] c = {'你'};
byte[] b2 = "你".getBytes("GBK"); // {0xC4, 0xE3}
byte[] b3 = "你".getBytes("8859_1"); // {0x3F} ('?') 無法對應
String.length() 回傳 char 數,不同編碼下位元組長度不同,分頁截斷易產生亂碼。
InputStreamReader / OutputStreamWriter 是橋樑:建構子必須傳入 encoding,否則用平台預設編碼(中文 Windows = GBK/Big5,Linux/英文 Windows = ISO-8859-1)。FileReader/FileWriter 無法指定編碼,跨平台極不穩定。javac -encoding GBK MyJsp.java
.java,將字面字串編譯為 Modified UTF-8 存入 .class。-encoding,依平台預設編碼讀取 → 跨平台編譯會產生不同 bytecode。String str = "你"; 在中文平台編譯 → runtime char[] = 0x4F60;英文平台編譯 → runtime char[] = 0x00C4, 0x00E3(誤將位元組當 Unicode)。<%@ page contentType="text/html;charset=GBK" %>,容器依此編碼讀取 .jsp 檔;否則預設 ISO-8859-1。.java,再用 javac -encoding UTF-8 編譯。HttpUtils.parsePostData、HttpRequestAdapter 可見)。response.setContentType("text/html;charset=GBK") 影響 out 寫入器編碼。<jsp:include> 編碼缺陷:早期 Tomcat 解析器漏掉 encoding 屬性,需自行修補原始碼或避免使用。javac -encoding ISO-8859-1 編譯charset=GBKnew String(param.getBytes("8859_1"), "GBK");檔案上傳分頁極難處理。<%@ page contentType="text/html;charset=GBK" %>
<% request.setCharacterEncoding("GBK"); %> // 必須在讀取參數前呼叫
server.xml 設定 URIEncoding="GBK" 統一 GET 參數解碼server.xml 設定 URIEncoding="UTF-8"characterEncoding=UTF-8<%@ page contentType="text/html;charset=UTF-8" %>web.xml 設定 <filter> CharacterEncodingFilter UTF-8 true </filter>(Spring 提供)server.xml <Connector URIEncoding="UTF-8" />CHARSET=utf8mb4)jdbc:mysql:///db?useUnicode=true&characterEncoding=UTF-8.java、.jsp、.properties 檔案以 UTF-8 無 BOM 儲存