Java中的字串

來源:互聯網
上載者:User

標籤:

Java中的字串常量

Java中的字串是不可改變的,當然,它與字串常量,比如:

public static final String a="123";

是不同的,此處指的是a只能指向字串123,而我們今天指的不可改變指的是字串在記憶體中不可變,現在我們看一個例子:

package com.test;/** * Created by siege on 2015-08-02. */public class TestString {    public static void main(String[] args) {        String a="0";        for (int i = 1; i <10 ; i++) {            a+=i;            System.out.println(a);        }    }}

其輸出結果為:

01
012
0123
01234
012345
0123456
01234567
012345678
0123456789

當然,結果並不奇怪,表面上看起來,a的值一直在變,好像a最初指向的“0”變成了"0123456789",其實不是這樣的,實際上上述的字串都存在記憶體中,只不過a的引用一直在變。

實際上,在java中存在一個字串池(String pool,由JVM維護),當我們給變數a賦值一個字串時(比如”0”),首先,JVM會在String pool中找是否有”0”這個字串,如果有,那麼直接將該字串在String pool中的引用返回,使a指向這個引用,如果沒有的話,那麼建立該字串,然後將該字串的引用返回給a,舉例說明:

package com.test;/** * Created by siege on 2015-08-02. */public class TestString {    public static void main(String[] args) {       String a="hello";        String b="hello";        System.out.println(a==b);    }}

其結果為true,這就說明了a和b指向的是同一個字串的引用,但是如果我們這樣建立:

package com.test;/** * Created by siege on 2015-08-02. */public class TestString {    public static void main(String[] args) {       String a="hello";        String b=new String("hello");        System.out.println(a==b);    }}

其結果為false,究其原因,使用new建立的字串對象是存在堆中的,故他們的地址不同。繼續看:

public class TestString {    public static void main(String[] args) {        String a="abc";        String b="edf";        String c=a+b;        System.out.println(c=="abcdef");    }}

其結果為false,這說明了c指向的是堆記憶體中的”abcdef”,不信我們繼續看:

public class TestString {    public static void main(String[] args) {        String a="abc";        String b="edf";        String c=a+b;        String d="abcdef";        System.out.println(c==d);    }}

其結果也為false,這樣就證明了c指向的並不是String pool中的常量”abcdef”,那麼它必然是指向堆中的”abcdef”,進一步深入,實際上 String a="abc" 在編譯期間JVM就已經將a變數的值”abc”放入String pool中了,String c=a+b只有在運行期間才能知道c的值,故其是在堆中建立的,在堆中建立的還有兩個String對象,a和b,他們是將String pool中的a,b的值賦值到堆中去的,在堆中建立兩個對象,然後建立對象c,將"abcdef" 的堆地址賦給c。

public class TestString {    public static void main(String[] args) {        String a="abc"+"def";        System.out.println(a=="abcdef");    }}

輸出結果為true,說明JVM是將"abcdef" 放入String pool中的。

public class TestString {    public static void main(String[] args) {        String a="abc";        String b=a+"def";        System.out.println(b=="abcdef");    }}

其結果為false,這也說明了b是在堆中建立的。

public class TestString {    public static void main(String[] args) {        String a=new String("abc");        String b=a.intern();        String c="abc";        System.out.println(b==c);    }}

intern()方法是將堆中建立的a對象的字串放入到String pool,不過在放入之前先檢查是否有改字串,有的話就無需放入,沒有的話就將其放入String pool中,並將其引用返回給b。故上述結果為true

關於設定String pool’的意義在於減少相同內容字串的建立,節省記憶體空間,缺點就是在存放字串到String pool中是需要進行計算該String pool中是否已經有該字串了。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Java中的字串

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.