java什么是國際化
java什么是國際化
我們知道Unicode為國際化(I18n)提供了堅(jiān)實(shí)的基礎(chǔ)。但是Unicode不等同于國際化。使用Unicode的Java語言,若是使用不當(dāng),同樣達(dá)不到國際化的目的。讓我們來看一下Java是怎樣處理Unicode的。
Java的字符類型
和C語言不同,Java的字符類型“char”是一個(gè)16位長的整數(shù),而C語言的char是8位,等同于一個(gè)字節(jié),只能表示單字節(jié)的字符(拉丁語系文字)。所以Java可以直接用一個(gè)char來表示一個(gè)Unicode字符(包括中文、英文、日文……),大大簡(jiǎn)化了字符和字符串的操作。
因?yàn)镴ava字符總是Unicode字符,所以在后文中,如果不加說明,“字符”或“char”都是指16位的Unicode字符,而“字節(jié)”或“byte”都是指8位字節(jié)。
編碼(encoding)
然而,當(dāng)今多數(shù)計(jì)算機(jī)系統(tǒng),都是以字節(jié)為存儲(chǔ)運(yùn)算的基本單元。這就使得在Java中,用Unicode表示的字符串無法直接寫到文件中或保存到數(shù)據(jù)庫中。必須以某一種方式,將字符串轉(zhuǎn)換成便于傳輸和存儲(chǔ)的字節(jié)流才行。這種將Unicode字符轉(zhuǎn)換成字節(jié)的操作,就叫做“字符編碼”(encoding)。
前面說過Unicode有兩種字節(jié)表示法:UTF-8和UTF-16。所以將Unicode以UTF-8和UTF-16編碼是最直接和自然的事了。以上面的“我愛Alibabaあいう”為例,用Big-endian(高位字節(jié)在前,低位字節(jié)在后)的UTF-16編碼,可以表示成:
我們也可以把同樣的字符串轉(zhuǎn)換成UTF-8。UTF-8是變長的編碼,對(duì)于ASCII碼字符,不需要改變,就已經(jīng)是UTF-8了,但一個(gè)中文要用三個(gè)字節(jié)來表示:
使用UTF-16或UTF-8編碼的數(shù)據(jù),必須使用支持Unicode的軟件來處理,例如支持Unicode的文本編輯器。目前存在的大量軟件,不一定都支持Unicode。因此我們往往將Unicode轉(zhuǎn)換成某一種本地字符集,例如:
英文可轉(zhuǎn)換成ISO-8859-1。
中文可轉(zhuǎn)換成GB2312、GBK、BIG5或是GB18030等。
日文可以轉(zhuǎn)換成SJIS或ISO-2022-JP等。
韓文可以轉(zhuǎn)換成ISO-2022-KR等。
本地字符集名目之多,無法全部列舉。最重要是,大多數(shù)字符集只映射到Unicode中的部分字符,且字符集之間互相交錯(cuò),互不兼容。
那么,如果在將Unicode轉(zhuǎn)換到某一本地字符集時(shí),發(fā)現(xiàn)這一編碼字符集不包含這個(gè)字符,怎么辦呢?例如:“我愛Alibaba”這個(gè)字符串(簡(jiǎn)體中文),如果轉(zhuǎn)換成繁體中文的BIG5編碼,就會(huì)變成:“我?Alibaba”。原來,Unicode規(guī)定,轉(zhuǎn)換時(shí)碰到“看不懂”的字符,一律用“?(0x3F)”表示。
這就解釋了一種常見的“亂碼”情形:好端端的頁面,顯示在瀏覽器上卻變成了無數(shù)個(gè)問號(hào)。原因就是Java在輸出網(wǎng)頁時(shí),使用了錯(cuò)誤的編碼方式。