Java 9 及更高版本
从 Java 9 开始属性文件默认编码为 UTF-8,并且使用 ISO-8859-1 之外的字符应该可以开箱即用。
如果您使用 IDE 来编辑它们,那么您需要考虑到目前(2023 年 10 月)只能在 IntelliJ 中重新指示 IDE 使用 UTF-8 读取它们。
Eclipse 仍然顽固地尝试使用 ISO-8859-1 读取它们,导致 Mojibake 显示在其属性文件编辑器中。您需要使用通用文本编辑器*.properties
文件或在 IDE 外部编辑文件。
Java 8 及更早版本
The ResourceBundle#getBundle()在幕后使用PropertyResourceBundle when a .properties
文件被指定。这又默认使用Properties#load(InputStream)加载这些属性文件。按照javadoc,它们默认读取为 ISO-8859-1。
public void load(InputStream inStream) throws IOException
从输入字节流中读取属性列表(键和元素对)。输入流采用简单的面向行的格式,如 load(Reader) 中指定的并假定使用 ISO 8859-1 字符编码;即每个字节都是一个 Latin1 字符。非 Latin1 字符以及某些特殊字符使用 Java™ 语言规范第 3.3 节中定义的 Unicode 转义符在键和元素中表示。
因此,您需要将它们另存为 ISO-8859-1。如果您有任何超出 ISO-8859-1 范围的字符并且无法使用\uXXXX
离开头顶,因此你被迫将文件保存为 UTF-8,那么你需要使用原生2ascii将 UTF-8 保存的属性文件转换为 ISO-8859-1 保存的属性文件的工具,其中所有未覆盖的字符都转换为\uXXXX
格式。下面的示例转换 UTF-8 编码的属性文件text_utf8.properties
有效的 ISO-8859-1 编码属性文件text.properties
.
native2ascii -encoding UTF-8 text_utf8.properties text.properties
当使用 Eclipse 或 IntelliJ 等 IDE 时,当您创建.properties
文件并使用 IDE 自己的属性文件编辑器。它将透明地将超出 ISO-8859-1 范围的字符转换为\uXXXX
格式。另请参阅下面的 Eclipse 屏幕截图(请注意底部的“属性”和“源”选项卡,单击查看大图):
或者,您也可以创建自定义ResourceBundle.Control实现,其中您使用显式读取属性文件为 UTF-8InputStreamReader,这样你就可以将它们保存为 UTF-8 而无需麻烦native2ascii
。这是一个启动示例:
public class UTF8Control extends Control {
public ResourceBundle newBundle
(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
} finally {
stream.close();
}
}
return bundle;
}
}
可以按如下方式使用:
ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", new UTF8Control());
也可以看看: