51CTO的自測題《驗證你Java掌握程度的自測題(一)》中,最後一道題是關於Java字串所佔用的記憶體空間的,原題如:
出題者給的答案是A. 6個位元組。我認為不對。
String作為一個對象,絕不是僅僅包含字元集合這麼簡單,它一定還需要有用於對象的記憶體開銷,經查,有人根據JVM的記憶體結構給出了一個String所佔用的最少位元組數的計算公式
- Minimum String memory usage (bytes) = 8 * (int) ((((chars number) * 2) + 45) / 8)
且不說對象的額外開銷,就"學java"這幾個字元來說,佔多少位元組呢?6個位元組——也不對!
Java中字元是按16位的Unicode來儲存的,官方《The Java Tutorial》一書中“ Primitive Data Types”一章提到了這一點:
* char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive). |
那麼"學java"這5個字元就應該是5*16bit=10bytes,即佔用10位元組記憶體空間。
那麼出題者的答案6位元組是怎麼來的呢?試試下面這段代碼:
- public class Test {
- public static final void main(String[] args) {
- System.out.println("學java".getBytes().length);
- }
- }
是的,我相信簡體中文Windows使用者運行這段代碼都會得到6這個答案。為什麼"學java".getBytes()會得到6個位元組呢?不妨來看看getBytes()的文檔是怎麼說的
Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array. |
也就是說,getBytes()會按當前系統預設的字元集來對字串進行編碼。簡體中文Windows的預設字元集,是GBK,GBK中漢字是2個位元組,而ASCII佔1個位元組,所以"學java"是6個位元組。
如果你不清楚當前平台/系統的預設字元集,可以用這條語句來看看:
- System.out.println(java.nio.charset.Charset.defaultCharset().toString());
參考:http://jamesfancy.blog.51cto.com/2516291/665745