Java 中 String 字符串可以有多長?65535?
毫無疑問 String 是作為一個 Java 開發(fā)工程師天天都需要打交道的類,那么如果問你 String 字符串的最大長度是多少你知道嗎?
有的小伙伴可能想都沒想,就直接回答 65535,那么問題來了,真的嗎?今天阿粉就帶你研究一下。
首先對于 String 我們可以有下面幾種用法:
- 定義一個 String 類型的變量:private static final String STRING_TEST = "xxxxxxxxxxx"; 或者 String newString = "newString";
- 通過在方法中定義 String 類型的變量,通過字節(jié)流創(chuàng)建字符串:byte[] bytes = new byte[length];String s = new String(bytes);;
有朋友可能會說,這兩種不都是定義一個字符串變量,有什么區(qū)別嗎?表面上看是沒什么區(qū)別,但是實際上區(qū)別還是蠻大的。
首先第一種方式定一個靜態(tài)類變量,或者普通的字符串變量,這種形式字符串是存放在棧中的;而第二種方式字符串是存放在堆中的。這個時候有的小伙伴又要問了,這存在不同的地方有什么關(guān)系呢?首先這關(guān)系可大了!
當(dāng)字符串存放在棧中的時候,根據(jù) class 文件的結(jié)果規(guī)范,我們可以看到所采用的的存儲格式是這樣的:
- CONSTANT_Utf8_info {
- u1 tag;
- u2 length;
- u1 bytes[length];
- }
其中 u2 是一種類似于Java 中int 一樣的數(shù)據(jù)類型,只是表示的是一個 2 個字節(jié)的數(shù)據(jù)類型,只不過 int 是 4 個字節(jié),這也就意味著允許的最大長度為 65535 個字符。所以我們可以得出一個結(jié)果,當(dāng)字符串存放在棧內(nèi)存中的時候,字符串的長度可以達到 65535。
看到這里小伙伴又不耐煩了,說到:你看吧,我就說是 65535 吧,還不信。
別急,到這里我們才說了一半,接下來我們在看看第二種方式。很顯然第二種方式不管是通過字節(jié)流的方式,還是 new 一個對象,存放的位置都是早 Java 的堆內(nèi)存中,而且通過 String 的源碼,我們可以看到了,底層是通過一個 char[] 數(shù)組來存放的。
- private final char value[];
那么我們就知道了,字符傳的大小就跟數(shù)組的長度有直接關(guān)系了,另外在定義數(shù)組長度的時候,我們最多只能定義 int 類型的最大值,也就是Integer.MAX_VALUE = 0x7fffffff; 而且 String 類的 length() 方法的返回值也可以看出來,返回的類型是 int ,數(shù)值最大也是Integer.MAX_VALUE = 0x7fffffff;
- /**
- * Returns the length of this string.
- * The length is equal to the number of <a href="Character.html#unicode">Unicode
- * code units</a> in the string.
- *
- * @return the length of the sequence of characters represented by this
- * object.
- */
- public int length() {
- return value.length;
- }
所以看到這里,我們又得出了一個結(jié)果,**當(dāng)字符串存放在堆內(nèi)存的時候,最大的長度為 Integer.MAX_VALUE = 0x7fffffff; **。不過需要注意的是,這個數(shù)值是理論上的,其實很多虛擬機會在數(shù)組中加入一些字符,所以實際的數(shù)值是達不到這么多,另外我們在 ArrayList 中也可以看到這個驗證,這里定義的最大值就是Integer.MAX_VALUE - 8; 而不直接采用最大值。
此外上面說的最大值是在我們的虛擬機有這么大的內(nèi)存的前提下,如果說我們的虛擬機配置的內(nèi)存比這個要小,那也是達不到這么大。我們可以通過 JVM 參數(shù)來配置虛擬機的內(nèi)存大小,-Xms512m 設(shè)置堆內(nèi)存初始值大小。-Xmx1024m 設(shè)置堆內(nèi)存最大值。下面是阿粉在自己的電腦上測試的效果,可以看到,當(dāng)開始提示Requested array size exceeds VM limit,后面因為阿粉的電腦內(nèi)存不夠了,所以一直分配失敗,達不到最大值,只能降低長度了。
另外還要注意一個點,那就是我們在這里說的長度針對的都是英文字符,如果是是中文的話是沒有那么長的,那么如果對應(yīng)中文的話字符串會有多長呢?