java-字符串的建立和存儲機制

在Java語言這種,字符串起着很是重要的做用,字符串的聲明和初始化由如下兩種狀況: 設計模式

1》對於字符串String s1 = new String("abc")語句與String s2 = new String("abc")語句,存在兩種引用對象s1,s2,兩個內容相同的字符串對象"abc",他們在內存中的地址是不一樣的。只要是用到new總會產生新的對象。 函數

2》對於String s1 = "abc"和String s2 = "abc"語句,在JVM中存在一個字符串池,其中存有不少String對象,而且能夠被共享使用,s1,s2引用同一個常連池中的對象,其中String採用Flyweight設計模式,當建立一個字符串常量時,例如String s="abc",會首先在字符串常量池中查找是否存在相同的字符串定義,其判斷依據是String對象中的equals方法的返回值。若已經定義,則直接引用其定義,此時不須要建立新的對象;若是沒有定義,則首先建立對象,而後把他加入到字符串池中,再將他的引用返回。因爲字符串是不可變類,一旦建立好了就不可修改,所以字符串對象能夠被共享並且不會引發程序的混亂。 spa

    具體而言: 設計

        String s = "abc";    //把abc放在常量區中,在編譯時產生。 對象

        String s = "ab"+"c";    //把「ab」+「c」轉換成字符串常量「abc」放在常量區中 內存

        String s =new String("anc");    //在運行時把abc放在堆中 字符串

    例如: string

        String s1 = "abc"; //在常量區中存放了一個"abc"的字符串對象 編譯

        String s2 = "abc";//s2引用常量區中的對象,所以不會建立新的對象。 變量

        String s3 = new String("abc");//在堆中建立新的對象

        String s4 = new String("abc");//在堆中又建立一個新的對象

    爲了理解方便,能夠吧String s = new String("abc")語句的執行分類兩個過程;第一個過程就是新建對象的過程,即new String("abc");第二個過程就是賦值過程,即String s=。因爲第二個過程僅僅建立了一個字符串類型的變量,將一個字符串對象的引用賦值給s,所以這個過程當中不會建立新的對象。第一個過程new String("abc")調用String類中的構造方法:

    public String(String origin) {

        //body    

    }

    在調用這個構造函數時,傳入一個字符串常量,所以語句new String("abc")也就等價於"abc"和new String()兩個操做了。若在字符串池中不存在abc,則會建立一個新的字符串常量「abc」,並將其添加到字符串池中;若存在則不建立,而後new String()會在堆中建立一個新的對象,因此s3和s4是指向不一樣的String對象,地址天然也就不一樣了。如圖所示.

    


引伸:對於string類型的變量s,賦值語句s=null與s=""是否相同?

對於賦值語句s=null,其中s是一個字符串類型的引用,它不指向任一個字符串。而賦值語句s=""中的s是一個字符串類型的引用,它指向另外一個字符串(這個字符串的值爲"",也就是空字符串),所以兩則是不相同的。

常見的筆試題:

new String("abc")建立了幾個對象?

answer:一個或者兩個。若是常量池中原來有字符串"abc",那麼只建立一個對象;若是常量池中沒有字符串"abc",那麼就建立兩個對象(這兩個對象分別位於字符串常量池和堆中)。

最後吐槽:爲何答,案二字會被審覈不經過呢?想不明白

相關文章
相關標籤/搜索