1. 程式人生 > 其它 >Java中String類字面類與new 建立對像的區別

Java中String類字面類與new 建立對像的區別

Java中String類中字面類與new 建立對像的區別

在Java中的字串也是一種資料型別,只不過不是基本資料型別(基本資料型別如 int float double byte 等),而是引用型別(String這個類的物件).

一般我們在建立字串時一般有兩種方式:

一.用字面量來對已經宣告的字串物件進行賦值:
如:String s1 = "java";
上面式子就是通過宣告一個字串物件s1,並對它用字面量("java")進行初始化,此式子大概過程是:

JVM(java虛擬機器)會在常量池中檢查是否存在這樣一個常量"java",如果不存在就在常量池中新建一個字串常量物件,再將此物件的引用(即地址)返回,
即就是把"java"在常量池的物件(不存在就建立一個再返回)的地址值返回賦值給s1,


注意:雖然物件的值是地址,但是在對字串物件進行輸出時:

 System.out.println(s1);

結果是s1引用的內容java,而不是他的地址(這與其他物件不同,如直接輸出陣列名會得到地址值)

二.用構造方法String("內容") new一個物件:
我們都知道一般正常的類建立一個的過程一般是:

 類名 物件名 = new 類的構造方法名(引數);

對與字串類String 我們同樣可以使用這樣的辦法,只不過這樣建立的物件和我們用字面量建立有所不同

 String s2 = new String("java");

這樣建立一個物件的過程大概是:
首先JVM同樣會對常量池進行檢查(檢查的原因是節省記憶體避免重複建立物件造成記憶體浪費),如果在常量池內找不到就會在常量池建立一個物件(找得到則省略這一步),再在堆記憶體區

(JVM的一個記憶體區域,與常量池不在同一個區域)中新建一個物件引用常量池中的物件(也就是說在堆建立的堆物件的值是常量池中物件的地址),最後把在堆記憶體區建立的堆物件的地址值返回:此圖通過JVM中的記憶體結構簡單粗略的展示了兩種方式的建立物件的區別:

關於==運算子和equals()方法運算的區別:

1.==運算子:
其本質是值的比較(注意,物件是引用類型別,所以物件的值本質上也就是計算機虛擬記憶體的地址,類似C語言的指標),所以基於這一點,只有引用相同的物件兩個物件(實際上java中引用相同的兩個物件就是同一個物件)

即同一個物件(具有相同的引用)==運算的結果才為true

2.equals()方法:


對於非字串變數來說,"=="和"equals"方法的作用是相同的都是用來比較其物件在堆記憶體的首地址,即用來比較兩個引用變數是否指向同一個物件。 但是String類重寫了equals()方法,在字串中比較的是其字串的內容
下面看測試程式碼:

ublic class String_ {
	public static void main(String[] args) {
    String s1 = "java web";
    String s2 = new String("java web");
    System.out.println("new和字面量用==比較的結果為:"+(s1==s2)+"==比較的是地址值,基本資料型別比較是值");
    System.out.println("new和\"java\"用==比較的結果為:"+(s2=="java"));  //
    System.out.println("new和字面量相同一個字串用equals()方法比較的結果為:"+(s1.equals(s2)));
	}
}

執行結果如下:
通過上述測試我們可以看到:
  1)對於==,如果作用於基本資料型別的變數,則直接比較其儲存的 “值”是否相等;

    如果作用於引用型別的變數,則比較的是所指向的物件的地址
(其實本質上還是值的比較,因為引用資料型別的值是地址)

  2)對於equals方法,注意:equals方法不能作用於基本資料型別的變數

    如果沒有對equals方法進行重寫,則比較的還是是引用型別的變數所指向的物件的地址;(這一點和==差不多)

    但是諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的物件的內容。

總的來說就是:對於物件(引用型別的資料型別),無論是==還是equals()方法,比較的都是地址,但是有一些特殊情況(如String、Date等類)下,重寫了equals()方法,則比較的是引用物件的內容