由于基于Java的应用程序通常用于各种各样的操作系统和环境中,因此Java开发人员经常会遇到与基于字符的输入和输出有关的问题 。 涉及这些问题的博客文章包括《警察的恐怖:默认语言环境,默认字符集和默认时区》 ; 注释JDK默认数据 ; 编码问题:适用于linux和Java应用程序的解决方案 ; 愚蠢的Java字符串 ; Java:字符编码的粗略指南 ; 这篇文章标题太长,不能在这里列出 。
多年来,对Java进行了一些增强,以减少这些问题,但是当隐式使用默认字符集时,有时仍然存在一些问题。 《 Java Puzzlers 》一书中有一个难题(难题18),描述了与Java中“默认字符集的变量”有关的古怪之处。
由于所有这些与Java的默认字符集有关的问题,欢迎 JEP 草案 “ 使用UTF-8作为默认字符集 ”( JDK-8187041 )出现。 除了潜在地解决与默认字符集有关的问题外,该JEP还提供了有关这些问题的详细概述以及解决这些问题的替代方案。 JEP的“动机”部分目前总结了此JEP为何重要的原因:“使用默认字符集的API对Java平台的新开发人员来说是一种危害”,“对于有经验的开发人员来说,也是一个麻烦。”
“默认”字符集的问题由于使用不同的字符集以及JDK API中当前可用的不同方法(导致多个“默认”)而变得更加复杂。 这是要考虑的问题的细分。
- 描述文件内容字符集的“默认”字符集可能与描述文件路径字符集的“默认”字符集不同。
- Java系统属性
file.encoding
指定文件内容的默认字符集,其设置是java.nio.charsets.Charset.defaultCharset()返回的值。
- Java系统属性
- 与用于读取/写入文件内容的字符集有关的“默认”有两种类型。
- 某些JDK方法不允许指定字符集,并且始终仅针对该特定方法且不考虑任何语言环境或系统配置,都采用UTF-8的“默认”字符集。
JEP 草案 “ 使用UTF-8作为默认字符集 ”将帮助解决与默认用于读取和写入文件内容的字符集有关的不同类型“默认”相关的问题。 例如,它将消除使用平台默认方法写入文件并使用始终使用UTF-8的方法读取文件(无论平台默认字符集如何)可能引起的潜在冲突。 当然,仅在平台默认不是NOT UTF-8的情况下,这才是问题。
以下Java代码是一个简单的类,可打印出一些与字符集相关的设置。
显示默认字符集详细信息
package dustin.examples.charset;import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Locale;import static java.lang.System.out;/*** Demonstrate default Charset-related details.*/
public class CharsetDemo
{/*** Supplies the default encoding without using Charset.defaultCharset()* and without accessing System.getProperty("file.encoding").** @return Default encoding (default charset).*/public static String getEncoding(){final byte [] bytes = {'D'};final InputStream inputStream = new ByteArrayInputStream(bytes);final InputStreamReader reader = new InputStreamReader(inputStream);final String encoding = reader.getEncoding();return encoding;}public static void main(final String[] arguments){out.println("Default Locale: " + Locale.getDefault());out.println("Default Charset: " + Charset.defaultCharset());out.println("file.encoding; " + System.getProperty("file.encoding"));out.println("sun.jnu.encoding: " + System.getProperty("sun.jnu.encoding"));out.println("Default Encoding: " + getEncoding());}
}
下一个屏幕快照显示了在基于Windows 10的笔记本电脑上运行此简单类的结果,而未明确指定任何与字符集相关的系统属性,仅指定了file.encoding
系统属性,并指定了两个系统属性file.encoding
和sun.jnu.encoding
。
刚刚显示的图像演示了通过属性控制默认字符集的能力。 它还说明,对于此语言环境为en_US的 Windows环境,文件内容和文件路径的默认字符集均为windows-1252 ( Cp1252 )。 如果实现了本文中讨论的JEP草案 ,则即使对于Windows,文件内容的默认字符集也将更改为UTF-8。
当默认字符集更改为UTF-8时,在某些应用程序中可能会造成重大破坏。 JEP草案讨论了减轻这种风险的方法,包括通过预先将系统属性file.encoding
预先设置为UTF-8
来早期测试应用程序对更改的敏感性。 对于需要保留当前行为的情况(使用系统确定的默认字符集而不是始终使用UTF-8),JEP草案的当前版本建议支持指定-Dfile.encoding=SYSTEM
。
JEP当前处于草稿中,并且与任何特定的JDK版本都不相关。 但是,根据JDK邮件列表上的最新帖子 ,我很乐观地认为,在不久的将来,我们会将UTF-8视为JDK未来版本中的默认字符集。
翻译自: https://www.javacodegeeks.com/2018/02/java-may-use-utf-8-default-charset.html