JAVA——特殊類(1)——String類(1)
(一)兩種例項化方法
(二)字串的相等比較
(三)String的匿名物件
(四)兩種例項化的區別
(五)字串不可改變
(一)兩種例項化方法
- 直接賦值
即使用字串常量直徑二初始化一個String物件。
舉例如下:
String str1 = "hello";//直接賦值
System.out.println(str1);
//此時應該輸出 hello
- 構造法
即使用String的構造方法初始化字串物件。
舉例如下:
String str1 = new String("hello");//堆空間上開闢兩個記憶體塊
System.out. println(str1);
//此處輸出hello
(二)字串的相等比較
-
基本資料型別比較——使用 ==
-
引用資料型別比較——使用 equals 關鍵字
比如字串str1 和 str2 比較,str1.equals(str2) -
== 是用來進行數值比較的;若使用 == 用來比較字串,則比較的是字串物件的記憶體地址比較;
-
equals 則是進行字串物件的 內容比較。
舉例如下:
(1)基本資料型別可以使用 == 比較
public class TestString11_20{
public static void main(String[ ] args){
int num1 = 3;
int num2 = 3;
System.out.println(num1 == num2);
//此時結果為 true
}
}
執行結果如下:
(2)引用資料型別不可以使用 == 比較
public class TestString11_20{
public static void main(String[] args){
String str1 = "hello"; //匿名物件
String str2 = new String("hello");
System.out.println(str1 == str2);
//雖然str1 與str2內容一樣,但此處結果為false,說明str1 與 str2 不相等
//此時str1 與 str2 比較的是記憶體地址的值而並非內容
}
}
執行結果如下:
(3)字串比較使用equals
public class TestString11_20{
public static void main(String[] args){
String str1 = "hello"; //匿名物件
String str2 = new String("hello");
System.out.println("str1 equals str2 :"+str1.equals(str2));
}
}
執行結果如下:
(三)String的匿名物件
String str1 = “hello”;
hello即匿名物件,此時只不過給匿名物件起了名字 str1.
注意:
如果要判斷使用者輸入的字串是否等同於特定字串,一定要將特定字串寫 在前面。
(即比較時將匿名物件解除安裝前面。)
匿名物件.equals(使用者輸入的字串物件)。
原因:防止使用者輸入的字串為空。出現 NullPointerException 錯誤。
舉例如下:
public class TestString11_20{
public static void main(String[] args){
String str1 = null;
String str2 = "hello";
System.out.println("str1 equals str2 :"+str1.equals(str2));
}
}
執行結果會報錯:
應該嚴格將匿名物件解除安裝前面,這樣就不會報錯:
public class TestString11_20{
public static void main(String[] args){
String str1 = null;
String str2 = "hello";
System.out.println("str1 equals str2 :"+str2.equals(str1));
}
}
執行結果如下:
(四)例項化的區別
String類的設計使用了共享設計模式
在JVM底層實際上會自動維護一個物件池(字串物件池),如果現在採用了直接賦值的模式進行String類的物件 例項化操作,那麼該例項化物件(字串內容)將自動儲存到這個物件池之中。如果下次繼續使用直接賦值的模式 宣告String類物件,此時物件池之中如若有指定內容,將直接進行引用;如若沒有,則開闢新的字串物件而後將 其儲存在物件池之中以供下次使用
- 使用直接賦值法賦值的時候,使用的是共享池,如在堆記憶體中有一塊記憶體為 hello,若 str1,str2,,,等的物件內容都是hello,則它們指向同一塊堆記憶體,所以使用 == 比較的時候,它們的記憶體地址的值都相等。
- 使用構造方法的時候,在堆記憶體中本身就存在一塊記憶體,內容為hello,使用構造方法是將該內容拷貝一份,放在另外一塊堆記憶體上。所以說使用構造方法的時候,是開闢了兩個記憶體塊。所以記憶體地址的值已經發生變化。
(1)直接賦值:只會開闢一塊堆記憶體空間,並且該字串物件可以自動儲存在物件池中以供下次使用。
(2) 構造方法:會開闢兩塊堆記憶體空間,其中一塊成為垃圾空間,不會自動儲存在物件池中,可以使用 intern()方法手工入池。
(1)直接賦值法
public class TestString11_20{
public static void main(String[] args){
String str1 = "hello"; //堆空間上開闢一個記憶體塊並且共存(字串共享池)
String str2 = "hello";
String str3 = "hello";
System.out.println(str1 == str2);//true
System.out.println(str2 == str3);//true
System.out.println(str1 == str3);//true
}
}
執行結果如下:
(2)採用構造方法
public class TestString11_20{
public static void main(String[] args){
String str1 = "hello";
String str4 = new String("hello");//堆空間上開闢兩個記憶體塊
System.out.println(str1 == str4);//false
}
}
執行結果如下:
使用構造方法時,String提供方法入池操作:
public String intern() ;
public class TestString11_20{
public static void main(String[] args){
String str4 = new String("hello").intern();//入池操作
//String str4 = new String();
//str4 = str4.intern();
//該語句等價於上面的入池語句
String str1 = "hello";
System.out.println(str1 == str4);//false
}
}
執行結果如下:
(五)字串不可改變
字串一旦定義不可改變。
即字串本身不發生改變,是字串物件的引用一直在變化。
如果對字串進行修改,會建立新的字串物件。
不要在迴圈裡進行 大量的字串拼接。