jdk分析之String

來源:互聯網
上載者:User

標籤:style   blog   color   使用   java   ar   strong   資料   div   

 
public class StringDemo01 {    public static void main(String[] args) {        String s1 = new String("abc"); // a         String s2 = "abc"; // b         String s3 = new String("abc"); // c        System.out.println(s1 == s2); //false        System.out.println(s1 == s3); //false        System.out.println(s2 == s3); //false        System.out.println(s1 == s1.intern()); //false        System.out.println(s2 == s2.intern()); //true         System.out.println(s1.intern() == s2.intern()); //true        String lo = "lo";        String hel = "hel";        System.out.println("hello" == "hel" + "lo"); // d //true        System.out.println("hello" == "hel" + lo); // e //false        System.out.println("hello" == hel + "lo"); // f //false    }}
1、產生幾個對象

問題:當執行完程式的第a、b、c行之後分別產生幾個對象,分別是什嗎?原因?

1)執行完a後,產生2個對象:

首先先到String Pool中尋找是否有名稱為"abc"的字串,沒有的話在String Pool中新產生一個"abc"對象1,而new String("abc")操作又會在Java記憶體的堆中產生一個"abc"String類對象2,

變數s1是一個引用,存放在棧中並指向堆中的"abc"String對象;

2) 執行完b後,產生0個對象:

String s2= "abc"; 此句程式在執行過程中也會先到String Pool中尋找名稱為"abc"的字串對象,因為在String s1 = new String("abc");時已經在String Pool中產生了"abc"對象,故執行完

這句之後同樣存在於棧的s2對象指向String Pool中的"abc"String對象,即s2中存放"abc"String對象在String Pool中的地址;

3) 執行完c後,產生1個對象:

同樣的道理,首先會到String Pool中尋找是否有"abc"String對象,發現已經存在,然後又通過new的方式在中產生一個新的"abc"String對象,並將其地址賦給引用變數s3;

 

在此樣本中三個引用變數s1、s2、s3分別指向三個不同的對象,存放著三個不同的記憶體位址,故三者當中任意者用"=="來比較都是false。

s1--------堆中的一個對象,此對象是String Pool中對象的一個拷貝;

s2--------String Pool常量池中的"abc"String對象;

s3--------堆中的一個對象,此對象也是String Pool中對象的一個拷貝;

==判斷小結:

1)對於原生資料類型來說"=="比較的是資料的數值;
2)對於引用資料類型來說"=="比較的永遠是對象的記憶體位址 。

 

2、intern

查看JDK文檔可知如果有兩個String類型s和t,若且唯若s.equals(t)時,s.intern()==t.intern(),即如果s和t的內容相等時s.intern()和t.intern()都是返回String Pool中同一個對象的引用,

既然是同一個對象的引用地址肯定一樣。 分析s.intern()可知,首先到String Pool常量池中尋找是否有"abc"字串,如果有那麼s.intern()的傳回值就是常量池中"abc"的地址,如果沒有,那麼會先添加到string pool中去,然後將地址返回。

所以可以得到如下關係:s.intern()=s1.intern()=s2.intern()=s1

s1指向的是堆,而s1.intern()指向的是常量池中;

s2指向的是常量池,s2.intern()指向的也是常量池;

s1. intern()指向的是常量池,s2.intern()指向的也是常量池;

 

3、字串拼接

對於第d行"+"兩端是兩個字面值即常量,故會拼接成一個"hello",然後在String Pool常量池中可以找到,不產生新的對象,等號兩端的地址都是String Pool中" hello"的地址,所以相等,返回true。

對於第e,f行"+"兩端其中一個是字面值即常量而另一個則是變數,無法進行拼接,故會在堆中產生一個"abc"的對象,堆中一個對象和String Pool常量池中一個對象當然是兩個對象,地址值肯定不相

等,所以返回false。

常量池:JVM中一塊獨立的地區存放字串常量和基本類型常量(public static final)

 

4、在Java中一個字串能否表示一個漢字?

在Java中一個字元表示16位,相當於兩個位元組(1 byte = 8 bit),而一個漢字佔用兩個位元組。

 

5、String s = "Hello"; s = s + " world!";這兩行代碼執行後,原始的String對象中的內容到底變了沒有?

String對象的內容是不能改變的,最後雖然指向了helloworld,但是原始的String對象的內容還是hello並沒有改變,只是現在不指向它罷了。

 

6、String s = new String("xyz");建立了幾個String Object? 二者之間有什麼區別?

建立了2個對象,一個在string pool中一個在堆中

 

7、String 和StringBuffer的區別

String是final類型,內容不可改變的,StringBuffer的內容是可以改變的;

String重寫了equals和hashCode方法,而StringBuffer則沒有。

 

8、StringBuffer和StringBuilder的區別

StringBuffer是安全執行緒的;

StringBuilder是非安全執行緒的效能高點,推薦使StringBuilder,JDK5以後出現。

 

9、下面這條語句一共建立了多少個對象:String s="a"+"b"+"c"+"d"

一個。JVM在編譯時間會最佳化,相當於直接定義了一個”abcd”的字串;

String s = "a"+"b"+"c";會產生幾個對象?

只會產生一個對象,編譯期就能確定儲存到常量池中。

使用包含變數的字串串連符如"aa" + s1建立的對象是運行期才建立的,儲存在堆中;

 

10、String練習

String str1 = "a";String str2 = "b";String str3 = "ab";String str4 = str1 + str2;String str5 = new String("ab");System.out.println(str5.equals(str3));  //trueSystem.out.println(str5 == str3); //falseSystem.out.println(str5.intern() == str3); //trueSystem.out.println(str5.intern() == str4); //falseString a = new String("ab");String b = new String("ab");String c = "ab";String d = "a" + "b";String e = "b";String f = "a" + e;System.out.println(b.intern() == a); //falseSystem.out.println(b.intern() == c); //trueSystem.out.println(b.intern() == d); //trueSystem.out.println(b.intern() == f); //falseSystem.out.println(b.intern() == a.intern()); //trueString a = "abc";String b = "abc";String c = "a" + "b" + "c";String d = "a" + "bc";String e = "ab" + "c";System.out.println(a == b); //trueSystem.out.println(a == c); //trueSystem.out.println(a == d); //trueSystem.out.println(a == e); //trueSystem.out.println(c == d); //trueSystem.out.println(c == e); //true

 

jdk分析之String

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.