外码和内码的区别
外码是作为Java与外界传输字符的编码, 例如向文件写字符时候, 会使用默认的外码来将相应字符转换为相应字符集的字节数组, 例如FileWriter.write
内码则是Java虚拟机内部数据类型使用的编码, java创立之初就定位UTF-16, char在虚拟机内部就是使用UTF-16来存储字符的, 可以通过DateOutput.writeChars来检验是否是使用UTF-16.
JVM设置Java外码的流程
Java(JDK18则默认使用UTF-8)使用Charset.defaultCharset()获得的是系统环境的默认编码System.getProperty("file.encoding")作为默认外码, 所以在中国基本上就是GBK, 而通常使用的代码编辑器是UTF-8格式, 所以使用java 命令时候经常会遇到乱码
以下是JVM确认默认编码的流程
- 当前使用的电脑操作系统默认字符集是GBK
- 通过 java -Dfile.encoding=utf-8 将当前系统属性指定的字符集暂时改为UTF-8, 这只会影响JVM,不会影响到其他应用
- JVM启动, 通过System.getProperty("file.encoding")获得当前系统属性指定的字符集, 并以此修改JVM默认外码Charset.defaultCharset()
- 我们通过向外部文件写入文件时使用的就是这个默认外码Charset.defaultCharset(), 当然也可以自己指定其他字符集, JVM标准必须支持的charse包括在java.nio.charset.StandardCharsets, 最好使用这里的字符集, 能保证在所有的Java平台上都有实现
如下图: 在不指定Charset参数时创建OutputStreamWriter时, 会使用默认字符集, 而默认字符集是由当前系统属性指定, 再在JVM已有字符集中查找
如下图: 因为powershell的参数设定规则, 所以设置参数时要用引号包起来, 不然会被powershell误判, 当然也可以直接使用cmd