java中string默认unicode但io易乱码,因filereader等依赖系统编码;json转义uxxxx属正常;正则需用p{l}p{n}匹配unicode;数据库连接须显式指定utf-8编码参数。

Java中String默认就是Unicode,但读写文件时容易乱码
Java的String内部用UTF-16表示,天生支持Unicode字符,问题通常不出在内存里,而出在IO边界——比如读取文件、网络请求、控制台输出。不显式指定编码,FileReader或new Scanner(new File(...))会依赖系统默认编码(Windows上常是GBK),一遇到中文、emoji或阿拉伯文就变成???或。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 读文件优先用
Files.readAllLines(path, StandardCharsets.UTF_8),别用FileReader - 写文件用
Files.write(path, lines, StandardCharsets.UTF_8),避免FileWriter - 若必须用
InputStreamReader,务必传入StandardCharsets.UTF_8,不能只写new InputStreamReader(in) - IDE运行配置里检查
file.encoding是否为UTF-8(IntelliJ在Settings → Editor → File Encodings;Eclipse在Preferences → General → Workspace)
JSON序列化/反序列化时Unicode被转义成uXXXX
这是正常行为,不是bug。Jackson、Gson默认把非ASCII字符转成uXXXX形式,保证JSON字符串本身只含ASCII,兼容性好。但如果你看到日志里全是"name":"u4f60u597d",不是编码错了,是它故意这么干的。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- Gson里关掉转义:
new GsonBuilder().disableHtmlEscaping().create()(注意:这仅影响HTML相关字符,对Unicode无影响);真正控制Unicode转义的是.serializeNulls().setPrettyPrinting()之外的.disableEscapingHtml()不生效,要用.disableHtmlEscaping()配合.setLenient()也不行——正确做法是new GsonBuilder().disableHtmlEscaping().create()仍不会解u转义;实际应设gson.toJson(obj, writer)时确保writer本身是UTF-8编码的OutputStreamWriter,且Gson实例未开启escapeHtmlChars()(默认关闭);更直接的是用gson.toJson(obj)后,结果已是合法UTF-8字符串,只要输出端(如HTTP响应头)声明Content-Type: application/json; charset=utf-8,浏览器就能正确显示汉字 - Jackson用
objectMapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, false) - 关键点:转义与否不影响数据正确性,真正出问题的是HTTP响应头没写
charset=utf-8,或者前端没按UTF-8解析响应体
正则表达式匹配Unicode字母或数字失败
Java默认的w只匹配ASCII字母、数字和下划线,不认中文、日文平假名、阿拉伯数字等。写Pattern.compile("w+")想提取“你好123”,结果只能拿到空或单个ASCII字符。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 用Unicode属性类:
\p{L}匹配任意语言字母,\p{N}匹配任意数字,\p{IsHan}专指汉字 - 组合示例:
Pattern.compile("[\p{L}\p{N}]+")可匹配中英文混排的词 - 注意
\p{Alpha}是旧式写法,已废弃,优先用\p{L} - 如果要忽略大小写,用
Pattern.CASE_INSENSITIVE标志,但对中文等无效——本来就没大小写概念
数据库连接URL没设characterEncoding=UTF-8导致存取乱码
MySQL驱动默认用latin1连库,即使表字段是utf8mb4,Java发过去的UTF-8字节也会被服务端当latin1解,存进去就是乱码,再查出来还是错的。现象是:数据库里看着是乱码,但用命令行客户端连却正常——说明问题在JDBC这一侧。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- MySQL JDBC URL必须加参数:
?characterEncoding=UTF-8&useUnicode=true(useUnicode=true是前提,否则characterEncoding不生效) - PostgreSQL用
?charset=UTF-8,H2用;DB_CLOSE_ON_EXIT=FALSE;CHARSET=UTF-8 - 验证方式:执行
SELECT @@character_set_client, @@character_set_connection, @@character_set_results,三个值都应为utf8mb4 - Spring Boot配置里
spring.datasource.url要完整包含这些参数,别只写到?serverTimezone=UTC就停了
最易被忽略的是:数据库服务端配置(my.cnf里的collation-server和character-set-server)和建表语句(必须CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci)要配套,光改Java端没用。











