Java 語言中一個字符佔幾個字節?

Java基本數據類型

類型 大小 範圍/精度
byte 1字節 8位,最小值是 -128(-2^7); 最大值是 127(2^7-1)
short 2字節 16位,最小值是 -32768(-2^15); 最大值是 32767(2^15 - 1)
int 4字節 32位,最小值是 -2,147,483,648(-2^31); 最大值是 2,147,483,647(2^31 - 1)
long 8字節 64位,最小值是 -2^63; 最大值是 2^63 -1
float 4字節 32位,單精度、32位、符合IEEE 754標準的浮點數
double 8字節 64位,雙精度、64 位、符合IEEE 754標準的浮點數
char 2字節 單一的 16 位 Unicode 字符,最小值是 \u0000(即爲0);最大值是 \uffff(即爲65,535)
boolean 1位 1位,只有兩個取值:true 和 false

 

更多瞭解可參考我的這個字符集編碼與亂碼專題:字符集編碼與亂碼 - 肖國棟的i自留地,裏面有更詳細的介紹,包括很多圖示及代碼的例子。


首先,你所謂的“字符”具體指什麼呢?

如果你說的“字符”就是指 Java 中的 char,那好,那它就是 16 位,2 字節。

如果你說的“字符”是指我們用眼睛看到的那些“抽象的字符”,那麼,談論它佔幾個字節是沒有意義的。

具體地講,脫離具體的編碼談某個字符佔幾個字節是沒有意義的

就好比有一個抽象的整數“42”,你說它佔幾個字節?這得具體看你是用 byte,short,int,還是 long 來存它。 用 byte 存就佔一字節,用 short 存就佔兩字節,int 通常是四字節,long 通常八字節。 當然,如果你用 byte,受限於它有限的位數,有些數它是存不了的,比如 256 就無法放在一個 byte 裏了。

字符是同樣的道理,如果你想談“佔幾個字節”,就要先把編碼說清楚。

同一個字符在不同的編碼下可能佔不同的字節

就以你舉的“”字爲例,“”在 GBK 編碼下佔 2 字節,在 UTF-16 編碼下也佔 2 字節,在 UTF-8 編碼下佔 3 字節,在 UTF-32 編碼下佔 4 字節。

不同的字符在同一個編碼下也可能佔不同的字節

”在 UTF-8 編碼下佔3字節,而“A”在 UTF-8 編碼下佔 1 字節。(因爲 UTF-8 是變長編碼)

而 Java 中的 char 本質上是 UTF-16 編碼。而 UTF-16 實際上也是一個變長編碼(2 字節或 4字節)。

如果一個抽象的字符在 UTF-16 編碼下佔 4 字節,顯然它是不能放到 char 中的。換言之, char 中只能放 UTF-16 編碼下只佔 2 字節的那些字符。

而 getBytes 實際是做編碼轉換,你應該顯式傳入一個參數來指定編碼,否則它會使用缺省編碼來轉換。

你說“ new String(“字”).getBytes().length 返回的是3 ”,這說明缺省編碼是 UTF-8. 如果你顯式地傳入一個參數,比如這樣“ new String(“字”).getBytes(“GBK”).length ”,那麼返回就是 2.

你可以在啓動 JVM 時設置一個缺省編碼,

假設你的類叫 Main,那麼在命令行中用 java 執行這個類時可以通過 file.encoding 參數設置一個缺省編碼。 比如這樣:java -Dfile.encoding=GBK Main 這時,你再執行不帶參數的 getBytes() 方法時,new String(“字”).getBytes().length 返回的就是 2 了,因爲現在缺省編碼變成 GBK 了。 當然,如果這時你顯式地指定編碼,new String(“字”).getBytes(“UTF-8”).length 返回的則依舊是 3.

否則,會使用所在操作系統環境下的缺省編碼。

通常,Windows 系統下是 GBK,Linux 和 Mac 是 UTF-8. 但有一點要注意,在 Windows 下使用 IDE 來運行時,比如 Eclipse,如果你的工程的缺省編碼是 UTF-8,在 IDE 中運行你的程序時,會加上上述的 -Dfile.encoding=UTF-8 參數,這時,即便你在 Windows 下,缺省編碼也是 UTF-8,而不是 GBK。

由於受啓動參數及所在操作系統環境的影響,不帶參數的 getBytes 方法通常是不建議使用的,最好是顯式地指定參數以此獲得穩定的預期行爲。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章