Java 后端面试题库 / 全部题解免费阅读理解原理,有条理地回答

GB2312 与 ISO-8859-1 之间怎样转换?

先说出你的答案

定义边界、关键机制、一个反例;P8题再补容量、失败与验证。

查看完整题解

参考回答

直接回答

先纠正前提:Java String 存储文本值,本身不带“这是 GB2312 字符串”的编码标签。正确流程是用源编码把字节解码成文本,再用目标编码编码为字节。但 ISO-8859-1 不能表示普通中文,因此不能把任意中文无损转成该编码的正常文本。

讲清原理

要区分“真实转码”和“借用 Latin-1 搬运字节”。历史代码中把 GB2312 字节按 ISO-8859-1 构造成 String,有时只是让每个字节借一个字符位置暂存;这个字符串往往显示成乱码,并没有把中文变成 Latin-1 能表达的文字。

String.getBytes(Charset) 遇到不可映射字符可能使用替代内容,导致静默损失。重要数据转换应使用设置为 REPORT 的编码器,明确发现失败。已经丢失或替换的字节,通常不能靠再换编码自动恢复。

例子与易错点

var latin1 = java.nio.charset.StandardCharsets.ISO_8859_1;
var encoder = latin1.newEncoder().onUnmappableCharacter(
    java.nio.charset.CodingErrorAction.REPORT);
try {
    encoder.encode(java.nio.CharBuffer.wrap("中文"));
} catch (java.nio.charset.CharacterCodingException e) {
    System.out.println("目标编码不能表示中文");
}

新系统通常优先统一 UTF-8。排查乱码时先查清原始字节和每一步解码,别反复猜编码。

这道题,你掌握得怎么样?

掌握程度由你主动标记,阅读和收藏不会自动改变状态。