java中char是16位unicode码点,中文字符天然支持;真正需编码转换的是string与字节数组间操作,如utf-8/gbk互转,须严格匹配编解码 charset 以避免乱码。

Java 中 char 类型本身不涉及“编码转换”,它只是 16 位无符号整数,直接表示 Unicode 码点(U+0000 到 U+FFFF)。中文字符在 Java 中以 Unicode 形式天然支持,无需额外转码——但真正需要处理的是 char[] 或 String 在**字节序列层面**的编码转换(如 UTF-8、GBK),这发生在字符串与字节数组互转时。
理解 char 和编码的关系
char 是内存中的逻辑单元,不是字节。一个中文字符(如 '中')在 Java 中就是一个 char,其值是 Unicode 码点 '中' == '\u4e2d'(即十进制 20013)。它不等于 UTF-8 的 3 个字节,也不等于 GBK 的 2 个字节——那些是**序列化后的字节表现形式**,只在 I/O、网络传输或文件存储时才需指定编码。
String 与字节数组之间的编码转换(常用场景)
当你需要把含中文的字符串写入文件、发送 HTTP 请求,或从网页表单读取数据时,才真正用到编码转换。核心方法是:
- String → byte[]:用指定编码把字符串“编码”成字节
- byte[] → String:用指定编码把字节“解码”成字符串
示例:
String text = "你好"; // 编码为 UTF-8 字节数组 byte[] utf8Bytes = text.getBytes(StandardCharsets.UTF_8); // 编码为 GBK 字节数组(Windows 中文系统常见) byte[] gbkBytes = text.getBytes(StandardCharsets.GBK); // 用 UTF-8 解码字节数组(必须和编码时用同一 Charset) String fromUtf8 = new String(utf8Bytes, StandardCharsets.UTF_8); // 用 GBK 解码(若字节原是 GBK 编码,否则乱码) String fromGbk = new String(gbkBytes, StandardCharsets.GBK);
避免乱码的关键原则
- 编码和解码必须使用完全相同的字符集(如都用 UTF-8),否则必然出现???或 Mojibake
- 不要依赖平台默认编码(
new String(bytes)不带 Charset 参数),Windows 默认是 GBK,Linux/macOS 默认是 UTF-8,极易出错 - 读写文件时显式指定 Charset:
Files.readString(path, UTF_8)、Files.writeString(path, text, UTF_8) - HTTP 请求头中声明
Content-Type: text/plain; charset=utf-8,服务端也按此解码
特殊情况:处理超出 BMP 的中文字符(如生僻字、emoji)
Unicode 中部分汉字(如「?」U+20000)位于辅助平面(U+10000 以上),Java 中用两个 char(代理对,surrogate pair)表示。此时:
-
String.length()返回的是char个数(可能为 2),不是真实字符数 - 应使用
String.codePointCount(0, str.length())获取正确字符数 - 遍历时用
String.codePoints().forEach(...)或Character.toCodePoint(high, low)安全提取码点
这类字符在 UTF-8 中占 4 字节,在 GBK 中通常不支持(会丢失或替换)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











