Java中两种UTF-8字符串编码方式的区别及执行顺序疑问
字符串编码处理的区别与执行结果分析
让我一步步帮你理清楚这两种字符串处理方式的区别,以及执行那两行代码后的结果:
两种字符串处理方式的核心区别
方式一:String string2 = new String(string1.getBytes("UTF-8"), "UTF-8");
这个操作的逻辑很明确:
- 先把
string1中的字符按照UTF-8编码规则转换成字节数组 - 再将这个字节数组按照UTF-8解码规则转回字符串
- 因为UTF-8可以完整表示所有Unicode字符(Java的
String内部基于Unicode实现),只要原字符串本身是合法的,这个转换就是无损的——string2和string1的内容完全一致。本质上这是个冗余操作,不会改变字符串内容,但也不会引入问题。
方式二:String string3 = new String(string1.getBytes(),"UTF-8");
这个操作存在明显的风险,问题出在无参的getBytes()方法上:
getBytes()不带参数时,会使用当前系统的默认字符编码(比如Windows默认是GBK,Linux/macOS默认是UTF-8)把字符串转成字节数组- 之后再用UTF-8解码这个字节数组
- 如果系统默认编码和UTF-8不一致(比如GBK),原本用GBK编码出来的字节序列,用UTF-8解码时会因为不符合编码规则,出现大量乱码(通常是
�或其他无法识别的字符)。只有当系统默认编码恰好是UTF-8时,结果才会和原字符串一致,但这种情况完全依赖运行环境,代码的可移植性极差。
结论:方式一是安全但冗余的操作,方式二是危险且可能导致乱码的错误操作。如果你的目标是确保字符串的UTF-8编码逻辑,方式一其实没必要,方式二则绝对不能用。
执行两行代码后的string1变化
我们拆成两步分析:
第1行:
string1 = new String(string1.getBytes("UTF-8"), "UTF-8");
如前所述,这一步是UTF-8编码再解码的无损转换,执行后string1的内容和执行前完全一样,没有任何变化。第2行:
string1 = new String(string1.getBytes(),"UTF-8");
这一步的结果完全取决于你的系统默认编码:- 如果系统默认编码是UTF-8:
getBytes()得到的是UTF-8字节数组,再用UTF-8解码后,string1内容依然和最初一致 - 如果系统默认编码不是UTF-8(比如GBK):
getBytes()用GBK编码原字符串得到字节数组,再用UTF-8解码就会出现乱码,string1的内容会变成一堆无法识别的字符或替换符
- 如果系统默认编码是UTF-8:
内容的提问来源于stack exchange,提问作者no_name22
相关产品推荐
相关产品推荐

