乱码问题详解:String.getBytes和new String

乱码问题根源:编码与解码所用的字符编码方式不一致

编码: 从文字到0、1的映射
解码: 从0、1到文字的映射
乱码问题展示代码:

//使用指定的编码方式将此String编码为字节数组
byte[] b_GBK = "你".getBytes("GBK");
byte[] b_UTF8 = "你".getBytes("UTF-8");
byte[] b_ISO88591 = "你".getBytes("ISO8859-1");

//不同的编码方式编码同样的字符所对应的映射规则是不一样的
System.out.println(Arrays.toString(b_GBK));
System.out.println(Arrays.toString(b_UTF8));
System.out.println(Arrays.toString(b_ISO88591));

//对字节数组按照指定的字符编码方式解码
System.out.println(new String(b_UTF8, "UTF-8"));
System.out.println(new String(b_UTF8, "ISO8859-1"));
System.out.println(new String(b_ISO88591, "UTF-8"));

输出为:

[-60, -29]
[-28, -67, -96]
[63]
你
ä½ 
?

第二行乱码因为:编码UTF-8,解码ISO8859-1,编解码所用的字符编码方式不一致
第三行乱码因为:编码ISO8859-1,解码UTF-8,同上

结论:只要保持编解码所用的字符编码方式一致就可以避免乱码

但有时会遇到我们获取到的数据已经按错误的字符编码方式解码的情况,那么如何复原呢?

解决思路:

  • 1.按错误字符编码方式编码(复原为原始byte数组)
  • 2.按正确字符编码方式解码

示例代码:

//UTF-8编码
byte[] b_utf = "你".getBytes("UTF-8");
//ISO8859-1解码
String before = new String(b_utf, "ISO8859-1");
System.out.println("before = " + before);

//已经乱码,乱码后续处理:
//ISO8859-1编码(复原字节数据)
byte[] b_iso = before.getBytes("ISO8859-1");
//UTF-8解码(正确解码)
String after = new String(b_iso, "UTF-8");
System.out.println("after = " + after);

输出为:

before = ä½ 
after = 你
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java String 类型 API 测试代码 1.String和char[]之间的转换 toCharArray(); 2.Stringbyte[]之间的转换 getBytes() Arrays工具类 : Arrays.toString(names) StringString replace(char oldChar, char newChar) String replace(CharSequence target, CharSequence replacement) String[] split(String regex) boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引 int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始 int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引 int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索 boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束 boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始 boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始 int length():返回字符串的长度: return value.length char charAt(int index): 返回某索引处的字符return value[index] boolean isEmpty():判断是否是空字符串:return value.length == 0 String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写 String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写 String trim():返回字符串的副本,忽略前导空白和尾部空白 boolean equals(Object obj):比较字符串的内容是否相同 boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写 String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+” String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。 String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值