Java 內部統一使用 Unicode(UTF-16)存儲字符,但 .properties 文件常按系統默認編碼(中文環境多為 GBK)或 UTF-8 保存。Properties.load() 默認按 ISO-8859-1 讀取,導致中文變亂碼。解決核心:將文件中非 ASCII 字符轉為 \uXXXX Unicode 轉義序列,使文件僅包含 ASCII 字符,載入時無歧義。
位於 JAVA_HOME/bin/native2ascii.exe,專門將本地編碼文件轉為 Unicode 轉義文件。
native2ascii -encoding <源文件編碼> <源文件路徑> <目標文件路徑>
假設源文件 D:\src\resources.properties 為 GBK 編碼含中文,需轉為 D:\classes\resources.properties:
native2ascii -encoding GBK D:\src\resources.properties D:\classes\resources.properties
轉換後文件中文變為 \u4E2D\u6587 形式,Java 讀取自動還原為正確字符。
<target name="convert-props">
<exec executable="${java.home}/../bin/native2ascii">
<arg value="-encoding"/> <arg value="GBK"/>
<arg value="${src.dir}/resources.properties"/>
<arg value="${build.dir}/resources.properties"/>
</exec>
</target>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>native2ascii-maven-plugin</artifactId>
<version>1.0-beta-1</version>
<executions>
<execution>
<id>convert</id>
<phase>generate-resources</phase>
<goals><goal>native2ascii</goal></goals>
<configuration>
<encoding>GBK</encoding>
<src>src/main/resources</src>
<dest>target/classes</dest>
</configuration>
</execution>
</executions>
</plugin>
Java 9 起 Properties.load(Reader) 支持直接讀取 UTF-8 文件,無需轉義:
try (Reader r = new InputStreamReader(Files.newInputStream(path), StandardCharsets.UTF_8)) {
props.load(r);
}
但為兼容舊版本、舊系統,native2ascii 仍是最通用、穩健的方案。
Properties 亂碼本質是「文件編碼 ≠ 讀取編碼」。native2ascii 將非 ASCII 統一轉為 \uXXXX 轉義,消除編碼歧義,是跨平台、跨 JDK 版本最穩健的解法。建議納入構建腳本自動化,一次配置永久免維護。