1. 故事背景

小T是个测试MM,小C是个程序猿,今天早上他们又为一个bug吵架了。

小T:“这个显示是bug,在我的浏览器上显示不正确”

小C:“这个bug我不认,在我的电脑上显示正常,是你的环境有问题吧?”

小T:“我不管,反正我这个显示不正确,就是个bug”

小C:“我。。。。。。。。。。。。。。。。。”

最终leader出面,大家做到一起查找问题。(为防止公司信息泄露,下面为模拟程序)

    public static void main(String[] args) throws UnsupportedEncodingException {
byte bytes[] = new byte[256];
for (int i = 0; i < 256; i++)
bytes[i] = (byte)i;
String str = new String(bytes);
for (int i = 0, n = str.length(); i < n; i++)
System.out.print((int)str.charAt(i) + " ");
}

小T首先展示程序输出:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 
65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533

小C也不甘示弱,在自己的电脑上运行,得到如下结果:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

leader检查了小C和小T的程序后,发现程序完全一样,为什么会出现这种情况呢?

2. 事故查找

经debug发现,小T和小C的程序在

String str = new String(bytes);

这段代码时发生了不同:

小C的代码str为:

小T的代码为:

其中65533的图片显示为:

推测可能是编码问题,深入其源码内部,看看

 /**
* Constructs a new {@code String} by decoding the specified array of bytes
* using the platform's default charset. The length of the new {@code
* String} is a function of the charset, and hence may not be equal to the
* length of the byte array.
*
* <p> The behavior of this constructor when the given bytes are not valid
* in the default charset is unspecified. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more control
* over the decoding process is required.
*
* @param bytes
* The bytes to be decoded into characters
*
* @since JDK1.1
*/
public String(byte bytes[]) {
this(bytes, 0, bytes.length);
}

翻译过来就是:在通过解码使用平台缺省字符集的指定byte 数组来构造一个新的String 时,该新String 的长度是字符集的一个函数,因此,它可能不等于byte 数组的长度。当给定的所有字节在缺省字符集中并非全部有效时,这个构造器的行为是不确定的。

罪魁祸首就是String(byte[])构造。

3. 问题解决

小C承认了自己的错误,小T也高兴得提了个bug。接下来小C就要修改掉这个bug了。

    public static void main(String[] args) throws UnsupportedEncodingException {
byte bytes[] = new byte[256];
for (int i = 0; i < 256; i++)
bytes[i] = (byte)i;
String str = new String(bytes,"ISO-8859-1");
for (int i = 0, n = str.length(); i < n; i++)
System.out.print((int)str.charAt(i) + " ");
}

指定字符集后,小T和小C又能愉快得玩耍了。

总结

每当你要将一个byte 序列转换成一个String 时,你都在使用某一个字符集,不管你是否显式地指定了它。如果你想让你的程序的行为是可预知的,那么就请你在每次使用字符集时都明确地指定。

参考资料:

【1】java解惑

【2】https://www.jianshu.com/p/52fd2a304228

【3】http://www.mytju.com/classcode/tools/encode_utf8.asp

你的环境有问题吧?--byte数组转字符串的疑惑的更多相关文章

  1. php byte数组与字符串转换类

    <?php /** * byte数组与字符串转化类 * @author ZT */ class Bytes { /** * 转换一个string字符串为byte数组 * @param $str ...

  2. Byte数组和字符串相互转换的问题

    第一:需求:将文件转成byte数组,之后转成字符串返回.过滤器接收到响应内容后,需要将响应的内容转成byte数组. 第二:我刚开始的做法: Controller:byteArr = Conversio ...

  3. VB Byte数组转字符串问题

    在c#中,byte转换为字符串的过程中,如果byte的值为0,则转换成字符串时变为’\0’字符,’\0’字符在C#中意味着字符串结束,如果后面再有字符,则读取字符串的程序也不能读取和显示出来. 但是在 ...

  4. byte[] 数组和字符串的转换,与byte[] 数组和int类型的之间的转化

    我们先来看看byte bool  int ushort  等的定义 首先时byte[]数组与string之间的转换 string 转换位byte[] 数组 string str = "1-1 ...

  5. c++中byte数组与字符串的转化

    我们不讨论与字符集有关的内容,只讨论在字节流传递过程中的问题. 我们在做一系统操作时会需要使用到数据流,比如接收网络数据,文件数据,图片数据,原始数据大多是以byte数组的形式提供,与其它语言(c#, ...

  6. C++ BYTE数组转字符串

    第一种情况: BYTE[0]=Ox12 BYTE[1]=0x34 BYTE[2]=0x56 最后要转换成字符串123456 另外一种情况: BYTE[0]=Ox12 BYTE[1]=0x34 BYTE ...

  7. .NET如何快速比较两个byte数组是否相等

    目录 前言 评测方案 几种不同的方案 For循环 Memcmp 64字长优化 SIMD Sse Avx2 SequenceCompare 总结 参考文献 前言 之前在群里面有群友问过一个这样的问题,在 ...

  8. go语言:多个[]byte数组合并成一个[]byte

    场景:在开发中,要将多个[]byte数组合并成一个[]byte,初步实现思路如下: 1.获取多个[]byte长度 2.构造一个二维码数组 3.循环将[]byte拷贝到二维数组中 package gst ...

  9. byte数组和File,InputStream互转

    1.将File.FileInputStream 转换为byte数组: File file = new File("file.txt"); InputStream input = n ...

随机推荐

  1. P3355 骑士共存问题 二分建图 + 当前弧优化dinic

    P3355 骑士共存问题 题意: 也是一个棋盘,规则是“马”不能相互打到. 思路: 奇偶点分开,二分图建图,这道题要注意每个点可以跑八个方向,两边都可以跑,所以边 = 20 * n * n. 然后di ...

  2. CountHunter 6101 最优贸易 强联通缩点

    题目传送门 题解:强连通锁点之后. 就成了一副单向图. 然后对于每个点 找到 后面合法的点的最大值就好了. 合法就是后面的那个点可以走到n号点. 也可以正向跑一遍dij 求出到这个点的最小花费. 然后 ...

  3. lightoj 1245 Harmonic Number (II)(简单数论)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1245 题意:求f(n)=n/1+n/2.....n/n,其中n/i保留整数 显 ...

  4. open的正确使用

    open一个对象的时候,不确定他是图片还是文本啊 #----------------------- import io   with open('photo.jpg', 'rb') as inf:   ...

  5. 【LeetCode】22-生成括号

    22-生成括号 题目描述 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", ...

  6. 持续集成高级篇之Jenkins Pipeline 集成sonarqube

    系列目录 前面章节中我们讲到了Sonarqube的使用,其实Sonarqube获取msbuild结果主要是执行三个命令,开始标记,执行msbuild,结束标记,这些都是命令,是非常容易集成到我们ci流 ...

  7. mysql设置updatetime字段每次修改时自动更新

    我们在数据库表设计阶段中都会加上CreateTime, UpdateTime字段, 在重要业务字段更新的时候,都会重新赋值UpdateTime字段,这个对后期查找分析业务数据变更时非常有用. 但是现在 ...

  8. 【第十五篇】easyui datagrid的列编辑,同时插入两张表的数据进去

    看图说话. 需求:插入两张表,上面的表单是第一张表的内容,下面的两个表格是第二张详情表的内容,跟第一张表的id关联 第二张表有一个列是需要用户手动填写添加的. 国际惯例,上代码 <div id= ...

  9. guava multimap介绍

    引用一篇别人的博客,理解理解 http://vipcowrie.iteye.com/blog/1517338

  10. Winform中使用FastReport的DesignReport时怎样给通过代码Table添加数据

    场景 FastReport安装包下载.安装.去除使用限制以及工具箱中添加控件: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...