1. 程式人生 > >String類(物件例項化、字串比較、物件池、字串常量不可變更)

String類(物件例項化、字串比較、物件池、字串常量不可變更)

String的兩種例項化方式
直接賦值和傳統例項化:

public class Stringob
{
    public static void main(String[] args)
    {
        String str1="hello";  //直接賦值 str是一個物件,那麼"hello" 就應該儲存在堆記憶體中,String類可以直接賦值,JDK所做的簡化
        String str2=new String("hello"); //傳統賦值 用new
        System.out.println(str1);  //hello  
        System.out.println(str2);  //hello
    }
}

字串相等比較
1.如果是==

用==比較:
String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1==str); // false  ==比較的是地址

2.用equals
public boolean equals(String anotherString); 是成員方法, 通過物件呼叫

// /////字串比較
public class Stringob
{
    public static void main(String[] args)
    {
        String str=null;  //假設有由使用者輸入為空
        //System.out.println(str.equals("hello"));  //報錯:NullPointerException
        System.out.println("hello".equals(str));  //推薦使用此種比較方法,將特定字串"hello"寫在前邊
    }
}

小建議:如果要判斷使用者輸入的字串時是否等同於特定字串,一定要將特定字串(String常量,任何的字串常量都是String的匿名物件,所以該物件不為null)寫在前面,避免空指標異常(NullPointerException)
面試題:==和equals的區別:
==比較兩個字串的地址,equals是比較兩個字串內容。

物件池:
JVM底層會自動維護一個字串的物件池,如果現在採用直接賦值的形式進行String的物件例項化,該物件會自動儲存在這個物件池中。如果下次繼續使用直接賦值的模式宣告String物件,此時物件池中如果有指定內容,則直接引用;如果沒有,則開闢新的堆空間後將其儲存在物件池中下次使用。

public class Stringob
{
    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
        //"hello"是直接賦值,已經在物件池,所以str2和str3也指向str1指向的內容
        String str4=new String("hello");
        System.out.println(str1==str4); //false  新開的空間不在物件池

        //手動入池  (本地方法):
        //public native String intern( );(本地方法,沒有方法體)
        String str5=new String("hello").intern(); //手動入池
        System.out.println(str5==str1); //true  因為str5入池
    }
}

面試題:String兩種例項化區別:

  1. 直接賦值:只會開闢一塊堆記憶體空間,並且該字串物件可以自動儲存在物件池中以供下次使用。
  2. 構造方法:會開闢兩塊堆記憶體空間,其中一塊成為垃圾空間,不會自動儲存在物件池中,可以使用intern()方法手工入池。
    (比如:String str=new String(“hello”) , "hello"成為垃圾空間,新new的空間str指向。)

字串常量不可變更
所有的語言對於字串的底層實現,都是字元陣列,陣列的最大缺陷就是長度固定。在定義字串常量時,它的內容不可改變。 即字串一旦定義後不可改變(字串內容不可變,但指向即引用可變)
現在看一組例項:

public class Stringob
{
    public static void main(String[] args)
    {
        String str="hello";
        str = str + " world";
        str+="!!!";
        System.out.println(str);  //hello world!!!  字串內容不可變,但引用可變
    }
}

在這裡插入圖片描述
注:只要物件不存在,就會有一段新堆空間。原則:字串不能改變太多(+=操作儘量少)
如:String str=“hello”
str+=“world”, //現在str指向"hello world", 有兩個垃圾空間 “hello”和"world"