为何CP1147编码下字符Đ调用getBytes返回替换字符3F而非AC?
问题原因及解决方案
核心问题是混淆了两个视觉相似但Unicode码点不同的字符:
- 你代码中使用的
"Đ"是U+00D0(拉丁大写字母Eth,字符为Ð),这个字符在CP1147字符集中没有对应的编码映射,因此Java会将其替换为默认的替换字符X'3F'(问号)。 - 而CP1147中X'AC'对应的是U+0110(拉丁大写字母带横杠的D,字符为Đ)——这两个字符外观几乎一致,但属于完全不同的Unicode字符。
验证与修复
要得到预期的X'AC',需要确保字符串使用的是U+0110而非U+00D0。可以通过以下方式修改代码:
// 直接用码点构造正确的字符U+0110 String value = new String(new int[]{0x0110}, 0, 1); byte[] sendRecord = value.getBytes("CP1147"); StringBuilder sb = new StringBuilder(); for (byte b : sendRecord) { sb.append(String.format("%02X", b)); } System.out.println(sb.toString()); // 输出AC Assertions.assertEquals("AC", sb.toString());
另外可以确认:Java的sun.nio.cs.ext.IBM1147字符集确实包含U+0110到X'AC'的映射,但未定义U+00D0的对应编码,这是导致替换的根本原因。
内容的提问来源于stack exchange,提问作者0c7
相关产品推荐
相关产品推荐

