程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 從內存方面說明Java中String與StringBuilder的機能差別

從內存方面說明Java中String與StringBuilder的機能差別

編輯:關於JAVA

從內存方面說明Java中String與StringBuilder的機能差別。本站提示廣大學習愛好者:(從內存方面說明Java中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類文件的字節碼敕令來獲得上述謎底。 例如代碼:

public static void main(String[] args) {
  String a = "Hello";
  String b = " world";
  String str = a + b + " !";
  System.out.println(str);
}

經由過程對象檢查到其對應的字節碼敕令以下:

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

String str = a + b + " !";

被編譯器轉換成了相似以下語句:

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

不只如斯,Java的編譯器也是一個比擬聰慧的編譯器,當+號拼接的全體是字符串字面量時,Java的編譯器將會在編譯時智能地將其轉換為一個完全的字符串。例如:

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

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

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

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

從上述可知,關於相似String str = str1 + str2 + str3 + str4,這類將多個字符串一次性拼接的操作,應用+號來停止拼接是完整沒有成績的。

在Java中,String對象是弗成變的(Immutable)。在代碼中,可以創立多個某一個String對象的別號。然則這些別號都是的援用是雷同的。
好比s1和s2都是”droidyue.com”對象的別號,別號保留著到真實對象的援用。所以s1 = s2

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。 例如:

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

編譯器編譯後的字節敕令以下:

從下面的圖片中我們可以曉得,每條+號拼接語句,都創立了一個新的StringBuilder對象。這類情形在輪回前提下表示得特別顯著,形成了絕對較年夜的機能消耗。是以,在多條語句中拼接字符串,激烈建議應用StringBuffer或StringBuilder來處置。

關於應用StringBuilder帶來的優化

另外,在應用StringBuffer或StringBuilder的時刻,我們還可使用以下方法,進一步進步機能(上面代碼以StringBuilder為例,StringBuffer與此相似)。

1.猜測終究取得的字符串的最年夜長度。

StringBuilder外部char數組的默許長度為16,當我們append追加字符串後跨越此長度時,StringBuilder會擴展外部的數組容量以知足須要。在這個進程中,StringBuilder會創立一個新的較年夜容量的char數組,並將原數組中的數據復制到新數組中。假如我們可以或許年夜致猜測到終究拼接獲得的字符串的最年夜長度,便可以在創立StringBuilder對象時指定適合年夜小的初始容量。例如,我們須要拼接取得含有100個字母a的字符串。便可編寫以下代碼:

StringBuilder sb = new StringBuilder(100);
for (int i = 0; i < 100; i++) {
  sb.append('a');
}
System.out.println(sb);

請依據現實情形停止均衡,以創立合適初始容量的StringBuilder。

2.關於單個字符,盡量地應用char類型,而不是String類型。

有些時刻,我們須要在字符串後追加單個字符(例如:a),此時應盡量地應用

sb.append('a');

而不是應用:

sb.append("a");

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved