你的环境有问题吧?--byte数组转字符串的疑惑
wptr33 2025-07-28 00:35 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的程序后,发现程序完全一样,为什么会出现这种情况呢?
事故查找
经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[])构造。
问题解决
小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
相关推荐
- HIVE 窗口函数详解(hive常用开窗函数)
-
什么是窗口函数窗口函数是SQL中一类特别的函数。和聚合函数相似,窗口函数的输入也是多行记录。不同的是,聚合函数的作用于由GROUPBY子句聚合的组,而窗口函数则作用于一个窗口,这里,窗口...
- SQL高效使用20招:数据分析师必备技巧
-
基础优化技巧善用EXPLAIN分析执行计划EXPLAINSELECT*FROMordersWHEREorder_date>'2024-01-01';...
- 答记者问之 - Redis 的高效架构与应用模式解析
-
问:极客程序员你好,请帮我讲一讲redis答:redis主要涉及以下核心,我来一一揭幕Redis的高效架构与应用模式解析...
- MySQL通过累计求新增(mysql新增表字段语句)
-
前两天的那篇内容《MySQL递归实现单列分列成多行》...
- 一文讲懂SQL窗口函数 大厂必考知识点
-
大家好,我是宁一。今天是我们的第24课:窗口函数。...
- 圣诞快乐:用GaussDB T 绘制一颗圣诞树,兼论高斯数据库语法兼容
-
转眼就是圣诞的节日,祝大家节日快乐。用GaussDBT(也就是GaussDB100)绘制一棵圣诞树,纯国产,更喜庆。话不多说,上图:SQL如下:SELECTCASEWHENENMOTE...
- Minitab:功能强大的质量管理、统计分析及统计图形软件
-
一、Minitab简介Minitab软件是为质量改善、教育和研究应用领域提供统计软件和服务的先导,是全球领先的质量管理和六西格玛实施软件工具及持续质量改进的良好工具软件,她具有强大的功能和简易的可视化...
- 如何熟练使用SQL查询(如何熟练使用sql查询内容)
-
要熟练使用SQL查询(StructuredQueryLanguage),你需要系统地从语法入门,到实战练习,再到性能优化与多表查询的掌握。下面是一条循序渐进、实战驱动的学习路径:第一阶段:S...
- SAP SE38如何在多个系统间同步代码
-
上一篇文章写了如何在多个系统之间同步开发对象:多套SAPERP之间一键同步ABAP开发内容,有兄弟问有没有简单办法同步SE38程序代码的,因为使用请求的方式同步代码有点小题大做了。...
- 技术栈:刷了百道SQL题,还是不会用?你应该这样补短板
-
这是来自用户的提问,也是很多人遇到的困惑:...
- mysql窗口函数为了解决更加复杂的问题
-
为了解决复杂问题的窗口函数我们先讲一下窗口函数是什么窗口和普通的函数作用相同在不同列上进行查询和返回比如我们有如下的表...
- MariaDB开窗函数(开窗函数 mysql)
-
在使用GROUPBY子句时,总是需要将筛选的所有数据进行分组操作,它的分组作用域是整张表。分组以后,为每个组只返回一行。而使用基于窗口的操作,类似于分组,但却可以对这些"组"(即窗口...
- 一篇文章搞定MySQL中的窗口函数(mysql常用的窗口函数)
-
我是孙斌,北理数学系毕业,分享数据分析相关知识,点击右上角“关注”,学习更多数据分析知识。在MySQL中,分组groupby一般和聚合函数连用,如groupby+sum,这样能够得到每个组的总和,...
- 一周热门
-
-
因果推断Matching方式实现代码 因果推断模型
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
git pull命令使用实例 git pull--rebase
-
git 执行pull错误如何撤销 git pull fail
-
面试官:git pull是哪两个指令的组合?
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)