国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

String、StringBuffer與StringBuilder的區別與聯系

2019-11-08 02:13:09
字體:
來源:轉載
供稿:網友
java編程中經常使用String,StringBuffer和StringBuilder或許僅常用其中一個,其實StringBuffer與StringBuilder的方法都差不多, 傻傻的并不能區分這兩個有什么區別。最近偶遇到順便查閱資料總結下。String、StringBuffer與StringBuilder1、可變與不可變String是不可變的。看下String的源碼即可知。而StringBuffer與StringBuilder雖也是final,但都是繼承自AbstractStringBuilder,其append實現方法都是重寫AbstractStringBuilder里的。2、線程安全與不安全String中的對象是不可變的,可看為常量,所以是線程安全的StringBuffer也是線程安全的。其主要方法都加了synchronized,顯然線程安全。部分源碼如下:而StringBuilder的方法沒有加synchronized,在多線程下是不安全的。線程安全與不安全造成了StringBuilder與StringBuffer在效率方面有區別。這三者的速度排序是這樣的:String<StringBuffer<StringBuilder所以,在經常要操作字符串的情況下,多線程下,盡量用StringBuffer,單線程下,則盡量使用StringBuilder或許會有疑問:String為什么是最慢的,String不是經常看到String = str1+str2嗎?為什么是不可變的?其實jvm在實現String的加減并不是簡單的加減。Jvm有一個常量池,用來存放常量,并且是線程共享的。如:
String s1= "abc";String s2= "abc";實際上jvm會在常量池創建“abc”這個常量對象。而s2再次賦值為abc時,jvm會先到常量池查找,找到后,并不會再次創建這個對象,而只是返回了abc這個對象的引用而已,即s1和s2此時指的同一個對象,其值也是一樣。
String s3 = new String("abc");此時創建兩個對象,一個存放在堆中(String對象),一個存放在常量池中("abc"),還有一個對象引用s3,存放在棧。這個時候如果在new一個對象,如下:
String s4 = new String("abc");此時只創建一個對象,和存放在棧上的引用s4,jvm檢測到常量池里存有abc了,直接把abc引用給了s4.
String s5 = "ab"+"cd";這個加法編譯時會自動優化了。因為兩個常量的值都是已經確定了的。相當于String s5="abcd";所以這個過程還是很快的但是如果是下面的加法;
String s6 = "ab";String s7 = "cd";String s8 = s6+s7;String s9 ="abcd";則可就不一樣了。s6和s7都是對象,編譯時其值不是確定的,所以不會自動優化。而底層對這個加法的實現是這樣的。運行時jvm創建一個StringBuilder。并用s6所指的字符串完成初始化,然后用這個StringBuilder對象調用append方法合并s7的字符串cd,在調用StringBuilder的toString方法完成類型轉換,形成的新對象即引用給s8。這會導致s8!=s9.所以String的加法整體上說沒有StringBuffer和StringBuilder的效率高。
final String s1 = "cd;String s2= "ab" + s1;String s3 = "abcd";System.out.PRintln("s2 = s3 : "+ (s2 == s3)); 上面的str1在編譯時會被認為是常量,所以s2+s1這里會被編譯優化。所以導致最后s2和s3是同一個對象。運行結果為true
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 化州市| 广河县| 南郑县| 安义县| 泗洪县| 镶黄旗| 泰和县| 沧州市| 昭平县| 靖远县| 邵阳市| 拉萨市| 宁河县| 西乌| 开原市| 封丘县| 高邑县| 礼泉县| 福泉市| 宁明县| 丰宁| 扬州市| 油尖旺区| 景宁| 宜阳县| 金秀| 龙井市| 墨竹工卡县| 丹巴县| 高邑县| 禄丰县| 清远市| 乌鲁木齐市| 辽阳市| 福安市| 耿马| 繁峙县| 东至县| 大新县| 甘洛县| 自治县|