62,614
社区成员
发帖
与我相关
我的任务
分享
String str = "中国";
System.out.println("第一部分-------------------------------------------");
System.out.println(str.length());
System.out.println(str.getBytes().length);
System.out.println(new String(str.getBytes(),"UTF-8").length());
System.out.println(new String(str.getBytes(),"UTF-8").getBytes().length);
System.out.println("--------------------------------------------------");
String str2 ="abc中国";
System.out.println("第二部分-------------------------------------------");
System.out.println(str2.length());
System.out.println(str2.getBytes().length);
System.out.println(new String(str2.getBytes(),"UTF-8").length());
System.out.println(new String(str2.getBytes(),"UTF-8").getBytes().length);
System.out.println("--------------------------------------------------");
String str = "中国";
System.out.println(str.length()); //这些应该都没有问题,关键在下面
System.out.println(str.getBytes().length);//注意这里是得到的gbk的字节,一个汉字gbk编码是2个字节
System.out.println(new String(str.getBytes(),"UTF-8"));
//这里用得到的gbk的字节去转换成utf-8,需要注意的是一般情况下utf-8汉字占有3个字节,而acsll码在utf-8中是一个字节
//而编码转换的规则是对字节进行扫描,如果可以转换成1个字节的ascll就优先转换,可以转换成2个字节就优先转换成两个字节的utf-8编码
//* 0xxxxxxx (00-7f) ascll
// * 110xxxxx 10xxxxxx (c0-df)(80-bf) ascll和汉字之间的一些字符
//* 1110xxxx 10xxxxxx 10xxxxxx (e0-ef)(80-bf)(80-bf) 汉字
//* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (f0-f7)(80-bf)(80-bf)(80-bf)
//* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (f8-fb)(80-bf)(80-bf)(80-bf)(80-bf)
//* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (fc-fd)(80-bf)(80-bf)(80-bf)(80-bf)(80-bf)
//仔细看上面的utf-8的编码表 再看通过getBytes(),最终得到的二进制码是11010110 11010000 10111001 11111010(楼主可以自己去输出以下,注意负数的转换即可)
//第一个字节与第二个一直到最后字节组合不成utf-8编码(110开始的只有上面的第二行,但是下一个字节不是10******,因此要对第一个字节单独解码
//再看第二个与第三个字节为11010000 10111001 刚好是一个上面的第二行的范围内,所以对他们两个进行一个utf-8解码
//最后对11111010 进行解码
//通过以上分析可以知道得到的utf-8时3个字符,所以长度是3
System.out.println(new String(str.getBytes(),"UTF-8").getBytes().length);
String str2 ="abc中国";
System.out.println(str2.length());
System.out.println(str2.getBytes().length);
System.out.println(new String(str2.getBytes(),"UTF-8").length());
//01100001 01100010 01100011 11010110 11010000 10111001 11111010
//一样从左到右去解码 显然前三个字节满足第一个范围分别解码为abc,后面就与上面的分析一样了
//顺便说一句,如果不想得到乱码可以用getBytes("utf-8")
System.out.println(new String(str2.getBytes(),"UTF-8").getBytes().length);
补充点:
//对11111010进行解码,显然按照表格是没有结果的,所以结果是?可以通过这个来测试 11111010的对应的byte -6
byte []a=new byte[]{-6};
System.out.println(new String(a,"utf-8"));
//另外
System.out.println(new String(str.getBytes(),"UTF-8").getBytes().length);
//这个编译器应该做过一部分优化,getBytes后变成上面的那样的4个字节,由于utf-8解码后第一个字节不知道用utf-8编码是什么,所以维持
//原来的那个字节,后面能用utf-8编码的再进行gbk解码。最终得到长度。需注意的是utf-8跟gbk这里都是是占有两个字节。见上面的解码。
String str = "中国";
System.out.println("第一部分-------------------------------------------");
System.out.println(str.length());
System.out.println(str.getBytes().length);
System.out.println(str.getBytes("UTF-8").length);
System.out.println(str.getBytes("UTF-8").length);
System.out.println("--------------------------------------------------");
String str2 ="abc中国";
System.out.println("第二部分-------------------------------------------");
System.out.println(str2.length());
System.out.println(str2.getBytes().length);
System.out.println(str2.getBytes("UTF-8").length);
System.out.println(str2.getBytes("UTF-8").length);
System.out.println("--------------------------------------------------");