本文章分爲三個部分:html
一、建立字符串對象的兩種方式以及它們的存儲方式java
二、String a = new String("a")建立了幾個對象的問題面試
三、字符串小例子spa
----------------------------------------------我是友好的分隔線----------------------------------------------.net
在《Java核心技術I》中對String類的描述就是「因爲不能修改Java字符串中的字符,因此在Java文檔中將String類對象稱爲不可變字符串......編譯器可讓字符串共享」。但是在哪裏能夠實現「共享」這個操做呢?字符串池。3d
咱們知道建立一個字符串對象有兩種方式:1) 採用字面值的方式賦值 2) 採用new關鍵詞新建一個字符串對象。code
方式一:採用字面值的方式賦值htm
首先咱們先舉個小例子:對象
public class StringTest { public static void main(String[] args) { String a = "aaa"; String b = "aaa"; } }
通常的作法是直接用System.out.println(a==b);來判斷,此處用javap -v反編譯的方式來判斷a和b的值是否是來自同一個地方。blog
這裏的ldc的含義是:將常量值從常量池中取出來而且壓入棧中。
咱們能夠看到,a和b是指向同一個字符串對象的,由於"aaa"這個字符串對象在字符串池中,而字符串池是常量池的一種,並且咱們能夠從"LocalVariableTable"得知,在編譯期間,a和b的值就已經肯定好了。若是想要建立一個字符串對象,編譯器會先在字符串池中查找是否有相同字符串的對象,若是有,就能夠直接指向這個對象(多個變量可共享同一個對象),若是沒有,那就建立一個新的字符串對象。
方式二:採用new關鍵詞新建一個字符串對象
仍是先舉一個小例子:
public class StringTest { public static void main(String[] args) { String a = new String("bbb"); String b = new String("bbb"); } }
用javap -v反編譯以後獲得:
咱們能夠看到,這裏既有用在字符串池建立的對象的方式(紅色),也有調用String類並啓用來建立對象(綠色)。其實在使用new關鍵詞建立字符串對象的流程是這個樣子的:JVM會先在字符串池中尋找"bbb"這個對象,若是有,就不會在字符串池中建立這個對象,並且直接在堆建立「bbb」這個字符串對象,並將這個對象的地址返回給a;若是沒有,則會先在字符串池中建立"bbb"對象,而後再在堆中建立"bbb」這個對象並把這個對象的地址返回給a。由於a和b都是分別new了一個字符串對象,因此它們的字符串對象的地址是不一樣的。可是咱們能夠從"LocalVariableTable"中能夠看到,a和b變量在字符串池中的對象是在編譯期間就已經建立好了,可是由於a和b的字符串對象是用new的方式建立的,因此,a和b的建立須要在運行的時候才能所有完成。
總而言之,不管是用哪一種方式建立字符串對象,都須要在字符串池中進行字符串對象的建立,若是是用new關鍵詞建立對象的話,還須要在堆中建立對象並將對象的地址返回給變量。
----------------------------------------------我是友好的分隔線----------------------------------------------
有一道面試題是這樣子的,「String a = new String("a")」是建立了幾個對象?
其實,這道題能夠用咱們上面對字符串建立的分析來做答:建立了一個或者兩個對象。
這裏給兩個提示:1) String a = new String("a"); 2) String a = "a"; String b = new String("a");
具體要怎麼分析能夠參考這篇文章https://blog.csdn.net/limingchuan123456789/article/details/14150327,不過只要理解了上面的分析,這道題解答起來並不難。
----------------------------------------------我是友好的分隔線----------------------------------------------
下面是關於字符串的一些小例子,看看都能作對嗎?
public class StringTest { public static void main(String[] args) { String a = new String("aaa"); String b = "aaa"; String c = "a"+new String("aa"); String d = "a"+"aa"; System.out.println(a==b); System.out.println(a==c); System.out.println(b==c); System.out.println(b==d); System.out.println(c==d); } }
答案是:
false false false true false
參考:
https://www.cnblogs.com/fangfuhai/p/5500065.html
https://blog.csdn.net/limingchuan123456789/article/details/14150327