導航:首頁 > 編程語言 > javastring可變

javastring可變

發布時間:2023-01-14 13:53:00

1. 在java中,說String是不可變的,可是為什麼

ng對象的數據類型

1. 首先String不屬於8種基本數據類型,String是一個對象。

因為對象的默認值是null,所以String的默認值也是null;但它又是一種特殊的對象,有其它對象沒有的一些特性。

2. new String()和new String(「」)都是申明一個新的空字元串,是空串不是null;

3. String str=」kvill」;

String str=new String (「kvill」);的區別:

在這里,我們不談堆,也不談棧,只先簡單引入常量池這個簡單的概念。

常量池(constant pool)指的是在編譯期被確定,並被保存在已編譯的.class文件中的一些數據。它包括了關於類、方法、介面等中的常量,也包括字元串常量。

看例1:

String s0=」kvill」;

String s1=」kvill」;

String s2=」kv」 + 「ill」;

System.out.println( s0==s1 );

System.out.println( s0==s2 );

結果為:

true

true

首先,我們要知結果為道Java會確保一個字元串常量只有一個拷貝。

因為例子中的s0和s1中的」kvill」都是字元串常量,它們在編譯期就被確定了,所以s0==s1為true;而」kv」和」ill」也都是字元串常量,當一個字元串由多個字元串常量連接而成時,它自己肯定也是字元串常量,所以s2也同樣在編譯期就被解析為一個字元串常量,所以s2也是常量池中」kvill」的一個引用。

所以我們得出s0==s1==s2;

用new String() 創建的字元串不是常量,不能在編譯期就確定,所以new String() 創建的字元串不放入常量池中,它們有自己的地址空間。

看例2:

String s0=」kvill」;

String s1=new String(」kvill」);

String s2=」kv」 + new String(「ill」);

System.out.println( s0==s1 );

System.out.println( s0==s2 );

System.out.println( s1==s2 );

結果為:

false

false

false

例2中s0還是常量池中」kvill」的應用,s1因為無法在編譯期確定,所以是運行時創建的新對象」kvill」的引用,s2因為有後半部分new String(「ill」)所以也無法在編譯期確定,所以也是一個新創建對象」kvill」的應用;明白了這些也就知道為何得出此結果了。

4. String.intern():

再補充介紹一點:存在於.class文件中的常量池,在運行期被JVM裝載,並且可以擴充。String的intern()方法就是擴充常量池的一個方法;當一個String實例str調用intern()方法時,Java查找常量池中是否有相同Unicode的字元串常量,如果有,則返回其的引用,如果沒有,則在常量池中增加一個Unicode等於str的字元串並返回它的引用;看例3就清楚了

例3:

String s0= 「kvill」;

String s1=new String(」kvill」);

String s2=new String(「kvill」);

System.out.println( s0==s1 );

System.out.println( 「**********」 );

s1.intern();

s2=s2.intern(); //把常量池中「kvill」的引用賦給s2

System.out.println( s0==s1);

System.out.println( s0==s1.intern() );

System.out.println( s0==s2 );

結果為:

false

**********

false //雖然執行了s1.intern(),但它的返回值沒有賦給s1

true //說明s1.intern()返回的是常量池中」kvill」的引用

true

最後我再破除一個錯誤的理解:

有人說,「使用String.intern()方法則可以將一個String類的保存到一個全局String表中,如果具有相同值的 Unicode字元串已經在這個表中,那麼該方法返回表中已有字元串的地址,如果在表中沒有相同值的字元串,則將自己的地址注冊到表中「如果我把他說的這個全局的String表理解為常量池的話,他的最後一句話,「如果在表中沒有相同值的字元串,則將自己的地址注冊到表中」是錯的:

看例4:

String s1=new String("kvill");

String s2=s1.intern();

System.out.println( s1==s1.intern() );

System.out.println( s1+" "+s2 );

System.out.println( s2==s1.intern() );

結果:

false

kvill kvill

true

在這個類中我們沒有聲名一個」kvill」常量,所以常量池中一開始是沒有」kvill」的,當我們調用s1.intern()後就在常量池中新添加了一個」kvill」常量,原來的不在常量池中的」kvill」仍然存在,也就不是「將自己的地址注冊到常量池中」了。

s1==s1.intern()為false說明原來的「kvill」仍然存在;

s2現在為常量池中「kvill」的地址,所以有s2==s1.intern()為true。

5. 關於equals()和==:

這個對於String簡單來說就是比較兩字元串的Unicode序列是否相當,如果相等返回true;而==是比較兩字元串的地址是否相同,也就是是否是同一個字元串的引用。

6. 關於String是不可變的

這一說又要說很多,大家只要知道String的實例一旦生成就不會再改變了,比如說:String str=」kv」+」ill」+」 「+」ans」;

就是有4個字元串常量,首先」kv」和」ill」生成了」kvill」存在內存中,然後」kvill」又和」 「 生成 」kvill 「存在內存中,最後又和生成了」kvill ans」;並把這個字元串的地址賦給了str,就是因為String的「不可變」產生了很多臨時變數,這也就是為什麼建議用StringBuffer的原因了,因為StringBuffer是可改變的。
另外,團IDC網上有許多產品團購,便宜有口碑

2. Java中的String對象真的不可變嗎

不可以變的,您可以看下String的源碼,String底層是一個靜態數組常量

3. Java中的String對象是不可變的嗎 String

根據JDK中java.lang.String的源碼進行分析,從中可以得出String類型的對象不可變的原因,大致上有如下兩個:
1、java.lang.String類型在實現時,其內部成員變數全部使用final來修飾,保證成員變數的引用值只能通過構造函數來修改;
2、java.lang.String類型在實現時,在外部可能修改其內部存儲值的函數實現中,返回時一律構造新的String對象或者新的byte數組或者char數組;
第2的重要性在於,假如通過String類型的toCharArray方法可以直接訪問String類型內部定義的char數組,那麼即便String類型內部的char數組使用了final來修飾,也僅僅保證這個成員變數的引用不可變,而無法保證引用指向的內存區域不可變。由上述兩點,保證外部不可能修改java.lang.String類型對象的內部屬性,從而保證String對象是不可變的。
提到String,就不得不提一下JDK中存在另外兩個常用來表示字元串的類,StringBuffer和StringBuilder。根據注釋,StringBuffer可謂老資格了,從JDK1.0時即伴隨Java征戰世界,而StringBuilder直到JDK1.5時才出現。
面試時,StringBuffer和StringBuilder的區別也是常問的話題,有些沒有開發經驗,對多線程編碼不了解、對synchronized的使用不熟悉的兄弟,很容易在這個問題上吃虧。
StringBuffer和StringBuilder的共同點:
1、都是可變對象,對象內的字元緩存會隨著拼接操作而動態擴展;
2、用來完成字元串拼接操作;
3、構造時傳入內部緩存大小時,可以降低緩存擴展的次數,明顯提升字元串拼接操作的效率;
StringBuffer和StringBuilder的區別:
1、StringBuilder的方法都是線程不安全的,從另外一個角度講,StringBuilder類型的對象在做字元串拼接操作時,由於少了線程同步的操作,執行效率上有很大提升;
2、StringBuffer的方法都加上了synchronized關鍵字,因而在一定的場景下,StringBuffer類型的對象都是線程安全的,但在執行效率上,由於多了線程同步的操作,因而會有少許的損失;
在大多數場景下,字元串拼接操作都是不需要考慮多線程環境下對結果的影響的,因而使用StringBuilder類型可以提升代碼的執行效率。
在多個線程的代碼中共享同一個StringBuffer類型的對象時,需要關注synchronized關鍵字對最終結果的影響。由於StringBuffer類的實現中,僅僅對每個方法使用了synchronized修飾,這只能保證在多線程場景下,訪問StringBuffer對象的同一個方法時可以保證最終結果的一致性,假如一個線程訪問A方法,另外一個線程方法B方法,則由於加鎖對象的不同,可能會出現不一致的現象,這是需要程序員特別要注意的地方。類似的,可以參考Vector的實現和應用場景。

閱讀全文

與javastring可變相關的資料

熱點內容
能否給隱藏相冊加密 瀏覽:596
糖心app改什麼名 瀏覽:823
戰地1控伺服器如何部署 瀏覽:394
xp還原系統輸入命令 瀏覽:323
mysql命令行版本 瀏覽:303
如何進入itunes找文件夾 瀏覽:832
CAD中重復命令使用 瀏覽:477
心智pdf 瀏覽:475
網站電台直播間源碼 瀏覽:852
文件夾14c和18c的區別 瀏覽:34
android隱式調用 瀏覽:667
plc的編程指令邊沿繼電器 瀏覽:723
voc文件夾 瀏覽:865
租廣東聯通伺服器注意什麼雲空間 瀏覽:934
javascript高級程序設計pdf 瀏覽:292
pwm單片機原理 瀏覽:348
ai演算法在線修復圖片 瀏覽:982
scratch編程中如何做射擊游戲 瀏覽:479
at89c51編程器 瀏覽:344
項目經理叫醒程序員 瀏覽:344