.properties 文件必须在 java 9 之前以 ISO-8859-1 编码是真的吗?

Really true that .properties files must be encoded in ISO-8859-1 before java 9?

我经常读到 .properties 文件 should/must 用 ISO-8859-1 编码 在 Java 之前 9. 我在 UTF-8 中加载和存储 .properties 时从未遇到过问题。 还是建议 Resource Bundle 文件只使用 8859-1?

public static void utf8_test()
{
    Path pfile    = Paths.get("C:\temp_\properties_utf8.properties");
    Path pfileOut = Paths.get("C:\temp_\properties_utf-8_out.properties");
    Properties props = new Properties();

    try ( BufferedReader br = Files.newBufferedReader(pfile,StandardCharsets.UTF_8);
          BufferedWriter bw = Files.newBufferedWriter(pfileOut,StandardCharsets.UTF_8)
        )
    {
        props.load(br);
        props.setProperty("test","test prop;Гадание по телефону;öüµäß@;Euro sign;€");
        props.list(System.out);

        props.store(bw,"comment");

    } catch (Exception e) { e.printStackTrace(); }
} //--- end

The input file is:
foo = aaa
utf_test = Гадание
bar = bbb

The output file is:
#comment
#Wed Dec 25 15:11:28 CET 2019
utf_test=Гадание
bar=bbb
foo=aaa
test=test prop;Гадание по телефону;öüµäß@;Euro sign;€

属性文件

这是 Properties (Java 13) 的 class 文档:

The load(Reader) / store(Writer, String) methods load and store properties from and to a character based stream in a simple line-oriented format specified below. The load(InputStream) / store(OutputStream, String) methods work the same way as the load(Reader) / store(Writer, String) pair, except the input/output stream is encoded in ISO 8859-1 character encoding [emphasis added]. Characters that cannot be directly represented in this encoding can be written using Unicode escapes as defined in section 3.3 of The Java™ Language Specification; only a single 'u' character is allowed in an escape sequence.

The loadFromXML(InputStream) and storeToXML(OutputStream, String, String) methods load and store properties in a simple XML format. By default the UTF-8 character encoding is used, however a specific encoding may be specified if required. Implementations are required to support UTF-8 and UTF-16 and may support other encodings. An XML properties document has the following DOCTYPE declaration: [...]

这里是 Properties#load(InputStream) 的文档(同样是 Java 13):

Reads a property list (key and element pairs) from the input byte stream. The input stream is in a simple line-oriented format as specified in load(Reader) and is assumed to use the ISO 8859-1 character encoding [emphasis added]; that is each byte is one Latin1 character. Characters not in Latin1, and certain special characters, are represented in keys and elements using Unicode escapes as defined in section 3.3 of The Java™ Language Specification.

The specified stream remains open after this method returns.


资源包

这里是 PropertyResourceBundle 的 class 文档(同样,Java 13):

API Note:

PropertyResourceBundle can be constructed either from an InputStream or a Reader, which represents a property file. Constructing a PropertyResourceBundle instance from an InputStream requires that the input stream be encoded in UTF-8. By default, if a MalformedInputException or an UnmappableCharacterException occurs on reading the input stream, then the PropertyResourceBundle instance resets to the state before the exception, re-reads the input stream in ISO-8859-1, and continues reading. If the system property java.util.PropertyResourceBundle.encoding is set to either "ISO-8859-1" or "UTF-8", the input stream is solely read in that encoding, and throws the exception if it encounters an invalid sequence. If "ISO-8859-1" is specified, characters that cannot be represented in ISO-8859-1 encoding must be represented by Unicode Escapes as defined in section 3.3 of The Java™ Language Specification whereas the other constructor which takes a Reader does not have that limitation. Other encoding values are ignored for this system property. The system property is read and evaluated when initializing this class. Changing or removing the property has no effect after the initialization.

就是这个class变了。如果您查看 the Java 8 documentation of PropertyResourceBundle,您会发现它在使用 InputStream.

构造时仅接受 ISO 8859-1 编码