什么是字符串
字符串的分類
字符串的本質
String對象的對比
String,StringBuffer和StringBuilder的區(qū)別
字符串序列:
把多個字符按照一定的順序排列起來,
字符串:
把多個字符串串聯(lián)起來
字符串的分類
不可變得字符串:String (當前對象創(chuàng)建完成之后,該對象的內容是不能改變的,一旦改變就是一個新的對象)
可變的字符串:StringBuilder/StringBuffer (當前對象創(chuàng)建完成之后,對象的內容可以改變,內容改變之后,還是該對象)
字符串的本質
字符串的底層其實就是char[]
char 表示一個字符,char[] 表示同一種類型的多個數據
String str = "ABCD";? ?等價于? ?char[] chars = new char[]{"A","B","C","D"};
String
String類 (當前對象創(chuàng)建完成之后,該對象的內容是不能改變的,一旦改變就是一個新的對象)
String對象的創(chuàng)建
? ? 直接賦值一個字面量: String str = "ABC";
? ? 通過構造器創(chuàng)建: String str = new String("ABC");
String對象的空值
? ? 表示引用為空: String str = null;? (沒有初始化,沒有分配內存空間)
? ? 內容為空的字符串: String str = ""; (進行初始化,分配內存空間,但是沒有內容)
String字符串的比較
? ? "==" : 表示比較的引用的內存地址是否相同
? ? "equals" : String覆蓋Object中equals方法,比較的是字符串的內容
String str1 = "ABC"; 和 String str2 = new String("ABC");分別創(chuàng)建了幾個對象:
str1最多創(chuàng)建了一個對象,最少不會創(chuàng)建對象,因為如果在常量池中存在"ABC",那么str1就會直接引用常量池中的"ABC",不創(chuàng)建String對象,如果不存在,會在常量池中創(chuàng)建一個"ABC",再進行引用.
str2最多創(chuàng)建兩個對象,最少創(chuàng)建一個對象,str2會先在堆中創(chuàng)建一個堆空間,再向常量池中查找是否有"ABC",如果有直接引用,如果沒有進行創(chuàng)建.
常量池(用來存儲常量的地方,在方法區(qū)中)
? ? 編譯常量池:把字節(jié)碼加載進jvm的時候,存儲的是字節(jié)碼的信息
? ? 運行常量池:存儲常量數據
String對象的比較
? ? 單獨使用的""引號創(chuàng)建的字符串都是直接量,編譯期就確定要存儲在常量池中;
? ? 使用new String();創(chuàng)建的對象保存在堆空間中,運行期才創(chuàng)建;
? ? 多個" " + " "連接的字符串也是直接量,編譯期就確定要存儲在常量池中
? ? 使用包含String直接量(無final修飾)的字符串表達式(例如: "ABC" + str1)創(chuàng)建的對象時運行期才創(chuàng)建的,存儲在堆中
? ? 通過變量和或者調用方法連接字符串,都只能在運行期運行才能確定變量的值和返回的值.
String,StringBuffer和StringBuilder的區(qū)別
? ? String是不可變得字符串
? ? StringBuilder和StringBuffer都是可變的字符串,功能都相同
區(qū)別
? ? StringBuffer中的方法都是用了Synchronized修飾,表示同步的,性能低,但是線程安全
? ? StringBuilder中的方法沒有使用Synchronized修飾,性能高,但是線程不安全(建議使用)
在使用StringBuilder無參構造器的時候,底層會自動創(chuàng)建一個長度為16的char數組,當傳入的數據大于16個字符的時候,會自動的擴容(會重新創(chuàng)建一個更大的數組,將之前的數據還要拷貝到新的數組中),性能會下降,所以建議當知道要傳入多少字符時,直接在構造器中設置.
<完>