小白们在不同平台上使用String.getBytes(),会发现同样的字符得到的字节数组不同样。明显这是依赖于平台的默认字符集。
这可以从源码注释中得知:其中,默认的charset是Charset.defaultCharset()
其实Charset.defaultCharset()是受到 jvm参数 -Dfile.encoding=UTF-8 的影响。在启动jvm时如果没有指定编码,那么就以平台默认编码。因而,在大部分windows系统,我们ANSI 是GBK ,所以getBytes()的结果是GBK格式。
我们来做个实验即可明了:
1) 在IDE中,例如IDEAJ中,如果我们没有指定file.encoding的值,那么IDE默认会“偷偷”给我们设置为UTF-8:
如果我们需要指定,则在这里修改即可:
2)不在IDE中的情况。没有IDE的“偷鸡摸狗”行为,如果我们没有指定,则默认按照操作系统的ANSI 编码。
如果我们手动指定了file.encoding参数,那么也会输出结果也会改变:
总结:
由上面,我们可以看到getBytes() 其实是受到很多因素影响的。为了提高可控性,我不建议大家直接用getBytes(),而是每次都手动指定编码:getBytes("****"),这样才不会受操作系统等因素影响。(毕竟乱码问题往往涉及因素、环节较多,排查起来会有点困难)
注意:很多人在这里又容易混淆,误以为JVM中字符内码 也变成 -Dfile.encoding指定编码格式了。这是错误的,也是容易混淆的。一定要记住:JVM中字符内码只会是UTF-16格式!!-Dfile.encoding指定编码格式是在平时转化成字节数组、IO流处理等才起作用。