在Java中,字符串存放在常量池中,new方法創建的對象存放在heap(堆內存)中。
String a = "abc";//常量池
String b = new String("abc");//heap
a==b;//false
a.equal(b);//true
1、Constant Pool 常量池的概念
在Java 編譯好的class文件中,有個區域被稱爲Constant Pool,它是一個由數組組成的表,類型爲cp_info constant_pool[],用來存儲程序中使用的各種常量,包括Class、String、Integer等各種基本的Java數據類型。
String Pool是Constant Pool中存儲String常量的區域,對於值相同的String常量,在Constant Pool中只會創建一個,所以在編譯好的class文件中,只能找到一個對該常量的表示。
在程序執行的時候,Constant Pool會存儲在Method Area中,而不是堆中。對於“”,內容爲空的字符串常量,創建一個長度爲0,內容爲空的字符串放在Constant Pool中,而且Constant Pool可以在運行期動態擴展。
2、String 類
- String 使用private final char value[]來實現字符串的存儲。即String對象創建之後,就不能在修改此對象中存儲的字符串的內容。【String類型是不可變的】
- String類有一個特殊的創建方法,使用“”雙引號來創建。
new String("ABC");
,實際上創建了2個對象,一個是ABC通過“”創建,另一個是new創建,他們的創建時期不同,前者在編譯期,後者在運行期。 - Java中 String類型重載了+操作符,可以直接使用+來拼接字符串
- 運行期調用String類的intern()方法,可以向String Pool中動態添加對象
- String的創建方法有:1.” ” 2. new String() 3.new String(“abc”)以及其他一些重載的構造函數 4.+進行拼接
package T617;
/**
* Created by Promacanthus on 2017/6/17.
*/
public class T4 {
public static void main(String[] args) {
String string1 = "abcde";
String string2 = "abcde";
String string3 = new String("abcde");
String string4 = "ab";
String string5 = "cde";
String string6 = string4 + string5;
string1 = string2;//true
string1 = string3;//false
string3.intern();
string1 = string3;//true
string1 = string6;//true
}
}
3、String和StringBuffer的區別
3-1、String的創建:
String s = "hello";
JVM首先根據內容查找對象,沒找到則在heap上創建新對象,並賦予s,否則使用已經存在的。String s = new String("hello");
JVM直接在heap上創建新的對象,所以在heap中會出現內容一樣地址不同的String對象
3-2、String的比較:
- == 比較地址
- equals 比較內容
3-3、String和StringBuffer效率比較
String 比 StringBuffer快
String a = "a"+"b";
StringBuffer a = new String.append("a").append("b"):
後者比前者快
StringBuffer a = new StringBuffer();
for(int i - 0; i<5000;i++){
a.append("a"):
}
StringBuffer a = new StringBuffer(250000);
for(int i - 0; i<5000;i++){
a.append("a"):
}
因爲StringBuffer內部實現的是char數組,默認初始長度爲16,每當字符串長度大於char數組長度的時候,JVM會構造更大的新數組,並將原先的數組內容複製到新數組中
3-4、StringBuffer總結
- 不能簡單的任務append()效率好與+
- 不要使用new 創建String
- 注意intern()的使用
- 子啊編譯器能夠確定字符串的情況下,+效率高
- 避免使用+=來構造字符串
- 在聲明StringBuffer的到時候,指定合適的capacity,不要使用默認值
- 注意:
String s = "a"+"b";
和String s ="a"; s +="b";
後者開闢了2段內存
3-5、StringBuilder
StringBuilder和StringBuffer是一樣的,都是字符串變量,唯一的區別是前者不安全,後者線程安全。
在單線程的情況下,通常默認使用StringBuilder,因爲這個最快。
- 如果要操作少量的數據用 = String
- 單線程操作字符串緩衝區下操作大量數據 = StringBuilder
- 多線程操作字符串緩衝區下操作大量數據 = StringBuffer
三者在執行速度方面的比較:StringBuilder > StringBuffer > String
String:字符串常量
StringBuffer:字符串變量
StringBuilder:字符串變量