一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 從內存方面解釋Java中String與StringBuilder的性能差異

從內存方面解釋Java中String與StringBuilder的性能差異

2020-04-30 09:58CodePlayer JAVA教程

我們通常會發現使用StringBuffer或StringBuilder創建出來的字符串在拼接時回避String要來得快,尤其是StringBuilder,本文就從內存方面解釋Java中String與StringBuilder的性能差異,需要的朋友可以參考下

以前經常在網上看到關于Java字符串拼接等方面的討論。看到有些Java開發人員在給新手程序員的建議中類似如下寫道:

不要使用+號拼接字符串,要使用StringBuffer或StringBuilder的append()方法來拼接字符串。
不過,用+號拼接字符串就真的那么令人討厭,難道使用+號拼接字符串就沒有一點可取之處嗎?

通過查閱Java API文檔中關于String類的部分內容,我們可以看到如下片段:
“Java 語言提供對字符串串聯符號("+")以及將其他對象轉換為字符串的特殊支持。字符串串聯是通過 StringBuilder(或 StringBuffer)類及其 append 方法實現的。字符串轉換是通過 toString 方法實現的,該方法由 Object 類定義,并可被 Java中的所有類繼承。”

這段話很明確地告訴我們,在Java中使用+號拼接字符串,實際上使用的就是StringBuffer或StringBuilder及其append方法來實現的。

除了Java API文檔,我們還可以使用工具查看class類文件的字節碼命令來得到上述答案。 例如代碼:

?
1
2
3
4
5
6
public static void main(String[] args) {
  String a = "Hello";
  String b = " world";
  String str = a + b + " !";
  System.out.println(str);
}

通過工具查看到其對應的字節碼命令如下:

從內存方面解釋Java中String與StringBuilder的性能差異

從字節碼命令中,我們可以清楚地看到,我們編寫的如下代碼

?
1
String str = a + b + " !";

被編譯器轉換成了類似如下語句:

?
1
String str = new StringBuilder(String.valueOf(a)).append(b).append(" !").toString();

不僅如此,Java的編譯器也是一個比較聰明的編譯器,當+號拼接的全部是字符串字面量時,Java的編譯器將會在編譯時智能地將其轉換為一個完整的字符串。例如:

?
1
2
3
4
public static void main(String[] args) {
  String str = "Hello" + " world" + ", Java!";
  System.out.println(str);
}

Java編譯器直接將這種全是字面量的字符串拼接,在編譯時就轉換為了一個完整的字符串。

從內存方面解釋Java中String與StringBuilder的性能差異

就算+號拼接的字符串中存在變量,Java編譯器也會將最前面的字符串字面量合并為一個字符串。

?
1
2
3
4
5
public static void main(String[] args) {
  String java = ", Java!";
  String str = "Hello" + " world" + java;
  System.out.println(str);
}

從內存方面解釋Java中String與StringBuilder的性能差異

從上述可知,對于類似String str = str1 + str2 + str3 + str4,這種將多個字符串一次性拼接的操作,使用+號來進行拼接是完全沒有問題的。

在Java中,String對象是不可變的(Immutable)。在代碼中,可以創建多個某一個String對象的別名。但是這些別名都是的引用是相同的。
比如s1和s2都是”droidyue.com”對象的別名,別名保存著到真實對象的引用。所以s1 = s2

?
1
2
3
String s1 = "droidyue.com";
String s2 = s1;
System.out.println("s1 and s2 has the same reference =" + (s1 == s2));

并且在Java中,唯一被重載的運算符就是字符串的拼接相關的。+,+=。除此之外,Java設計者不允許重載其他的運算符。

在Java中,唯一被重載的運算符就是字符串的拼接相關的。+,+=。除此之外,Java設計者不允許重載其他的運算符。

眾所周知,在Java 1.4版本之前,字符串拼接可以使用StringBuffer,從Java 1.5開始,我們可以使用StringBuilder來拼接字符串。StringBuffer和StringBuilder的主要區別在于:StringBuffer是線程安全的,適用于多線程操作字符串;StringBuilder是線程不安全的,適合單線程下操作字符串。不過,我們的大多數字符串拼接操作都是在單線程下進行的,因此使用StringBuilder有利于提高性能。

在Java 1.4之前,編譯器使用StringBuffer來處理+號拼接的字符串;從Java 1.5開始,編譯器大多數情況下都使用StringBuilder來處理+號拼接的字符串。

當我們在JDK 1.4的環境下編寫代碼時,對于上述這種一次性拼接多個字符串的情況,建議最好使用+號來處理。這樣,當JDK 升級到1.5及以上版本時,編譯器將會自動將其轉換為StringBuilder來拼接字符串,從而提高字符串拼接效率。

當然,推薦使用+號拼接字符串也僅限于在一條語句中拼接多個字符串時使用。如果分散在多條語句中拼接一個字符串,仍然建議使用StringBuffer或StringBuilder。 例如:

?
1
2
3
4
5
6
7
8
public static void main(String[] args) {
  String java = ", Java!";
  String str = "";
  str += "Hello";
  str += " world";
  str += java;
  System.out.println(str);
}

編譯器編譯后的字節命令如下:

從內存方面解釋Java中String與StringBuilder的性能差異

從上面的圖片中我們可以知道,每一條+號拼接語句,都創建了一個新的StringBuilder對象。這種情況在循環條件下表現得尤其明顯,造成了相對較大的性能損耗。因此,在多條語句中拼接字符串,強烈建議使用StringBuffer或StringBuilder來處理。

關于使用StringBuilder帶來的優化

此外,在使用StringBuffer或StringBuilder的時候,我們還可以使用如下方式,進一步提高性能(下面代碼以StringBuilder為例,StringBuffer與此類似)。

1.預測最終獲得的字符串的最大長度。

StringBuilder內部char數組的默認長度為16,當我們append追加字符串后超過此長度時,StringBuilder會擴大內部的數組容量以滿足需要。在這個過程中,StringBuilder會創建一個新的較大容量的char數組,并將原數組中的數據復制到新數組中。如果我們能夠大致預測到最終拼接得到的字符串的最大長度,就可以在創建StringBuilder對象時指定合適大小的初始容量。例如,我們需要拼接獲得含有100個字母a的字符串。即可編寫如下代碼:

?
1
2
3
4
5
StringBuilder sb = new StringBuilder(100);
for (int i = 0; i < 100; i++) {
  sb.append('a');
}
System.out.println(sb);

請根據實際情況進行平衡,以創建適合初始容量的StringBuilder。

2.對于單個字符,盡可能地使用char類型,而不是String類型。

有些時候,我們需要在字符串后追加單個字符(例如:a),此時應盡可能地使用

?
1
sb.append('a');

而不是使用:

?
1
sb.append("a");

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色综合网亚洲精品久久 | 青春学堂在线观看 | 亚洲欧美日韩天堂在线观看 | 精品一区二区国语对白 | 日本妇人成熟免费不卡片 | 精品女同同性视频很黄很色 | 五月天婷婷亚洲 | 青青五月天 | 97色伦亚洲自偷 | 性欧美sexvideo另类 | 99在线在线视频免费视频观看 | 日本xxxxxx片免费播放18 | 乌克兰肥熟 | 国产成人久视频免费 | 国产伦精品一区二区三区免费迷 | 波多野结衣178部中文字幕 | 亚洲精品久久久久久婷婷 | 双子母性本能在线 | 国产精品99爱免费视频 | 日本韩国在线 | 日本高清在线看 | 成人免费视频在 | 1024日韩基地 | 男人的视频网站 | 无人在线视频高清免费观看动漫 | 99在线观看视频免费精品9 | 色播影音先锋 | 草女人逼 | 亚洲网站大全 | 91啦在线视频 | 亚洲黄色色图 | 性欧美高清强烈性视频 | 鬼吹灯天星术在线高清观看 | 九九精品99久久久香蕉 | 色婷婷婷丁香亚洲综合不卡 | 91麻豆精东果冻天美传媒老狼 | 皇上好大好硬好涨好深好爽 | 欧美精品久久一区二区三区 | 久久亚洲精品AV无码四区 | 国产精品露脸国语对白手机视频 | 热久久亚洲 |