JAVA String對象的建立,javastring對象

來源:互聯網
上載者:User

JAVA String對象的建立,javastring對象

String對象的建立是比較特殊的,普通對象建立都是在堆中建立,String對象確不一定,下面看一段代碼

public class StringTest1 {public static void main(String[] args) throws Exception{String a = "abc";String b = "abc";String c = "ab";String d = new String("ab");System.out.println("a=" + a);//a=abcSystem.out.println("b=" + b);//b=abcSystem.out.println("c=" + c);//c=abSystem.out.println("d=" + d);//d=abSystem.out.println("a==b is " + (a == b));//a==b is trueSystem.out.println("c==d is " + (c == d));//c==d is falseField field = String.class.getDeclaredField("value");field.setAccessible(true);char[] valueA = (char[]) field.get(a);char[] valueB = (char[]) field.get(b);char[] valueC = (char[]) field.get(c);char[] valueD = (char[]) field.get(d);System.out.println("a.value(" + valueA.hashCode() + ")=" + Arrays.toString(valueA));//a.value([1829164700)=[a, b, c]System.out.println("b.value(" + valueB.hashCode() + ")=" + Arrays.toString(valueB));//b.value([1829164700)=[a, b, c]System.out.println("c.value(" + valueC.hashCode() + ")=" + Arrays.toString(valueC));//c.value([2018699554)=[a, b]System.out.println("d.value(" + valueD.hashCode() + ")=" + Arrays.toString(valueD));//d.value([2018699554)=[a, b]valueA[0] = 'z';valueD[0] = 'x';System.out.println("a=" + a);//a=zbcSystem.out.println("b=" + b);//b=zbcSystem.out.println("c=" + c);//c=xbSystem.out.println("d=" + d);//d=xb}}


a跟b都是“abc”,測試結果a跟b的引用是相等的,value數組也是相等的,改變a的第一位,b也跟著變了。

c跟d都是“ab”,但是兩個引用是不相等的,d是用new建立的,這個時候才會在堆中建立對象,a,b,c三個引用都是直接指向常量池的對象的,但是下面c和d的value似乎又是同一個數組,改變d的第一位,c也變了,說明d在堆中建立的對象還是指向常量池的,所以用new的話就多建立了個對象。


還有一個經典的問題, String a = "a" + "b";建立了幾個對象。

一般來說應該是3個吧,一個"a",一個"b",一個結果"ab",下面寫一個簡單的類

public class StringTest2 {@SuppressWarnings("unused")public static void main(String[] args){String a = "a" + "b";}}

使用javap看一下位元組碼

javap -c StringTest2.classCompiled from "StringTest2.java"public class test.StringTest2 {  public test.StringTest2();    Code:       0: aload_0       1: invokespecial #8                  // Method java/lang/Object."<init>":()V       4: return  public static void main(java.lang.String[]);    Code:       0: ldc           #16                 // String ab       2: astore_1       3: return}

只有一個指令ldc           #16 ,從常量池裡加常量#16,很明顯這個常量就是ab,我就不去解析class檔案了,應該是沒錯,直接反編譯一下,得到的結果是

package test;public class StringTest2{  public static void main(String[] args)  {    String a = "ab";  }}

所以引用直接指向常量池"ab"了,就一個對象嗎,可能是編譯器最佳化的結果吧,如果有時間去單獨把class檔案一個位元組一個位元組解析出來結果應該更明了。

聯繫我們

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