1.
public class Str {
public static void main( String[]args ) {
//TODOAuto-generated method stub
StringStringa="hello";
StringStringb=newString("hello");
StringStringc=Stringb;
System.out.println(Stringa==Stringb);//false
System.out.println(Stringa==Stringc);//false
System.out.println(Stringb==Stringc);//true
System.out.println(Stringa.equals(Stringb));//true
System.out.println(Stringa.equals(Stringc));//true
System.out.println(Stringb.equals(Stringc));//true
}
}
“==”比較的并不是字符串包含的內(nèi)容,而是將字符存放的地址進行比較,屬于數(shù)值比較
比較字符串里面的內(nèi)容,可以使用String里面定義的方法
---比較內(nèi)容(與原定義有一些差別):public boolean equals (String str)
2. Stringinput=null;//假設(shè)為用戶輸入 如果(input.equals("hello"),就會產(chǎn)生空指向異常
if("hello".equals(input)) {//equals處理了null
System.out.println("Hello world!!");
//小技巧:在開發(fā)中,如果要要判斷輸入的內(nèi)容是否是某一字符串,一定要將字符串放在前面
}
3.
Stringstra="hello";
Stringstrb="hello";
Stringstrc="hello";
Stringstrd="world";
System.out.println(stra==strb);//true
System.out.println(stra==strc);//true
System.out.println(strb==strc);//true
System.out.println(stra==strd);//false
如圖所示

共享設(shè)計模式
(1)在JVM的層實際上會存在有一個對象池(不一定只保存 ?string對象) ,當(dāng)代碼之中采用直接賦值的方式定義了一個string類對象時,會將此字符串對象所使用的匿名對象入池保存, 而后如果后續(xù)還有其他string類對象也采用了相同賦值方式,且所設(shè)置同樣內(nèi)容時,那么將不會開辟新的堆內(nèi)存空間,而是使用已有的對象進行引用的分配,從而繼續(xù)使用
(2)采用構(gòu)造方法實例化
構(gòu)造方法如果要使用關(guān)鍵字new,一旦使用了關(guān)鍵字new,就表示要開辟新的堆內(nèi)存
Stringstr=newString("hello");
Stringstra="hello";
System.out.println(stra==str);//false

通過上圖可知,如果使用的時構(gòu)造方法string對象實例化的時候,那么最終的操作形式就變?yōu)榱碎_辟兩塊堆內(nèi)存空間(并且有一塊將成為了垃圾空間)。
除了內(nèi)存的浪費之外,如果使用了構(gòu)造方法定義的string類對象,其內(nèi)容不會保存在對象池之中,因為是使用了關(guān)鍵字new開辟的新內(nèi)存,如果希望現(xiàn)在開辟的堆內(nèi)存也可以進行對對象池的保存,可以進行手工入池:
public String intern();
Stringstr=newString("hello").intern();
Stringstra="hello";
System.out.println(stra==str);//true
面試題:請解釋String對象兩種實例化的區(qū)別
-- 1 直接賦值(Stringstra="字符串"),只會開辟一塊堆內(nèi)存空間,并會保存在對象池中以供下次重用
-- 2 構(gòu)造方法 (Stringstr=newString("字符串")),會開辟兩塊堆內(nèi)存空間,并且有一塊將成為垃圾,并且不會自動入池,但是可以手動使用intern方法手工入池