1 回答

TA貢獻(xiàn)2011條經(jīng)驗 獲得超2個贊
簡短的回答:
在第二個字節(jié)數(shù)組的最后 2 個字節(jié)中: [-32, -37] (0b11011011_11100000) 被編碼為:
By JDK 7: [-17, -65, -67] which is Unicode character 0xFFFD ("invalid character"),
By JDK 8: [-17, -65, -67, -17, -65, -67] which is 2 of 0xFFFD characters.
長答案:
數(shù)組中的某些字節(jié)序列似乎不是有效的 UTF-8 序列。讓我們考慮這段代碼:
byte[] bb = {55, 93, 97, -13, 4, 8, 29, 26, -68, -4, -26, -94, -37, 32, -41, 88};
for (byte b : bb) System.out.println(Integer.toBinaryString(b & 0xff));
它將打?。榱吮阌陂喿x,我手動添加了前導(dǎo)下劃線):
__110111
_1011101
_1100001
11110011
_____100
____1000
___11101
___11010
10111100
11111100
11100110
10100010
11011011
__100000
11010111
_1011000
正如您在UTF-8 維基百科文章中所讀到的,utf-8 編碼字符串使用以下二進(jìn)制序列:
0xxxxxxx -- for ASCII characters
110xxxxx 10xxxxxx -- for 0x0080 to 0x07ff
1110xxxx 10xxxxxx 10xxxxxx -- for 0x0800 to 0xFFFF
... and so on
因此,每個不遵循此編碼方案的字符都被 3 個字節(jié)替換:
[-17, -65, -67]
二進(jìn)制 1110 1111 10 111111 10 111101
Unicode 位是 0b11111111_11111101
Unicode 十六進(jìn)制是 0xFFFD(Unicode 的“無效字符”)
您的代碼打印的數(shù)組的唯一區(qū)別是如何處理以下字符,它們是第二個數(shù)組末尾的 2 個字節(jié):
[-32, -30] is 0b11100000_11100010, and this is not valid UTF-8
JDK 7 為這個序列生成了單個 0xFFFD 字符。
JDK 8 為這個序列生成了兩個 0xFFFD 字符。
RFC-3629標(biāo)準(zhǔn)沒有關(guān)于如何處理無效序列的明確說明,因此似乎在 JDK 8 中他們決定為每個無效字節(jié)生成 0xFFFD,這似乎更正確。
另一個問題是,當(dāng)你不應(yīng)該這樣做時,為什么你嘗試將這些原始的非 UTF-8 字節(jié)解析為 UTF-8 字符?
添加回答
舉報