String a = "hello";
String b = new String("hello");
final String c = "hello";
一、直接定義和new String的區別(即a和b的區別)
a指向常量池,而b指向堆。在java中,遇到new關鍵字,即會在堆中創建對象。String b = new String("hello")時會先去常量池中找是否有"hello",如果常量池中沒有,則先在常量池中新建"hello",然后在堆中創建一份拷貝對象,然后把堆內存中對象的地址賦給b。所以,String b = new String("hello");有可能創建了兩個對象。
所以 a == b 是false(==是直接比較地址值,而String的equals是先比較地址值,不相等再逐個比較字符,所以a.equals(b)是true)
二、final修飾String
final修飾類的時候表示類不可被繼承
final修飾方法的時候表示方法不能被重寫
final修飾變量的時候,表示變量不可變
所以,final String c = "hello";僅僅表示c不可變,不可再被重新賦值。(注意:這個String類是final的無關,那個是修飾String類的)
final修飾的String在相加的時候等同於字符串直接相加:
final a = "a",
final b = "b";
a+b == "a"+"b" == "ab"
因為+號兩邊都是常量,其值在編譯期就可以確定,由於編譯器優化,在編譯期就將+兩邊拼接合並了,直接合並成是一個常量"ab"。
但是如果把final去掉,a+b == "a" + "b" 就是false了,因為不用final修飾,a和b都是對象,在編譯期無法確定其值,所以要等到運行期再進行處理,處理方法:先new一個StringBuilder,然后append a和 b,最后相加的結果是一個堆中new出來的一個對象
可參考http://www.mamicode.com/info-detail-2370655.html