Java的final關鍵字與String的內部比較方法

來源:互聯網
上載者:User

標籤:

最近抽了點時間溫故,一些零零散散的問題還是整理了起來。我決定把一些曾經坑過自己的問題寫成部落格文章,給學弟學妹們一個警示吧。

今天的故事從一個例子開始:

@Testpublic void testFinal(){String s1="happyBKsOffer";String s2="happyBKs";final String s3="happyBKs";//s3.replace("h", "H");String s4=s2+"Offer";String s5=s3+"Offer";if (s1 == s4) {System.out.println("s1==s4");} else {System.out.println("s1!=s4");}if (s1 == s5) {System.out.println("s1==s5");} else {System.out.println("s1!=s5");}if (s1.equals(s4)) {System.out.println("s1 equals s4");} else {System.out.println("s1 not equals s4");}if (s1.equals(s5)) {System.out.println("s1 equals s5");} else {System.out.println("s1 not equals s5");}}

如果你看到這個代碼覺得莫名其妙並且伴隨著一點心虛,覺得不都是一樣的嘛,那麼恭喜你,看完了今天的例子,你就不用再往坑裡跳了。如果你一眼就看出了其中的坑,那麼也恭喜你,可以在我部落格下方評論處BB了,“這也算個問題,太基礎了”。(本文出自:http://my.oschina.net/happyBKs/blog/493904,請自行表明出處)

實際的運行結果如下:

s1!=s4s1==s5s1 equals s4s1 equals s5

有沒有一點出乎您的意料呢?


那麼這到底是怎麼了,s4和s5都是"happBKs"與"Offer"的憑藉,為什麼再==和equals下的結果不相同呢?

我們先說說==和equals方法的區別。這兩種判斷兩個值是否相等的方式其實存在本質的不同。==在判定基礎資料型別 (Elementary Data Type)時,沒有什麼不同,就是判斷連個基礎資料型別 (Elementary Data Type)的值是否相等;在判定對象資料類型時,會根據對象的類中覆蓋的equals方法來判定對象是否相等(如果沒有重新實作類別的equals方法,運行時會判定兩個對象的地址是否指向同一個對象)。

這時候,也許純潔無邪的孩子們會說:“我明白了,如果是int類型,那麼equals和==沒什麼區別,Integer類型則不是”。這時候,就會有人在旁邊陰笑,心裡想:“拆箱和裝箱都不懂,呵呵。。。結果肯定都一樣”

我給個例子:

@Testpublic void testInt(){int a=1,b=1;if (a == b) {System.out.println("a==b");} else {System.out.println("a!=b");}//if (a.equals(b)) {//System.out.println("a equals b");//} else {//System.out.println("a not equals b");//}Integer c=new Integer(1),d=new Integer(1);if (c == d) {System.out.println("c==d");} else {System.out.println("c!=d");}if (c.equals(d)) {System.out.println("c equals d");} else {System.out.println("c not equals d");}Integer e=1,f=1;if (e == f) {System.out.println("e==f");} else {System.out.println("e!=f");}if (e.equals(f)) {System.out.println("e equals f");} else {System.out.println("e not equals f");}}

那麼結果會怎麼樣呢?

a==bc!=dc equals d1e==fe equals f

是的,笑別人單純的人眼睛沒有瞎,真的結果就如同小朋友們料想的那麼單純。好了,別捶胸頓足故作恍然大悟了,單純的結果後面有著不單純的原因。

首先int的==比較沒有什麼可多說的。為什麼Integer類型的c和d,e和f在equals時會有兩種不同的記過呢?這是因為java編譯器的最佳化機製造就的:c和d各自初始化了一個物件類型,所以在==比較時,他們指的不是一個對象,所以==比較是不同的,而Integer的equals方法已經重寫,比較的是兩者實際的整型數值,所以是相等的。e和f的確用到了裝箱的拆箱,但是java編譯器在編譯時間做了最佳化,將兩個常量1裝箱後最佳化為一個對象,這樣e和f指向同一個Integer對象了,所以在==時是相同的。

回到我們剛才的執行個體中。s2和s3雖然都是"happyBKs",但是s2是final類型,s3是一般的類型。在java編譯器編譯時間,同樣會對常量數值做一些最佳化,編譯器會將s4=s2+"Offer"進行最佳化,因為s2是常量、"Offer"也是常量,所以,s4會在編譯後直接被轉換成s4="happyBKsOffer",而s1的初始化賦值也是常量"happyBKsOffer",所以編譯器會再次將它們最佳化為一個String對象,s1和s4指向同一個String對象,所以兩者在==是相同的。而s5=s3+"Offer",s3不是final的,所以必須在運行時計算,這樣s5隻有在運行時候才能產生一個對象,肯定與s1的那個不是同一個String對象,所以s1與s5在==比較時肯定是不同的。

明白了吧。也許你還是很揪心,我們這裡只給出一個建議吧:那就是,盡量養成用equals的好習慣!


好最後,我們隊final 本身再做個總結:final可以修飾類、方法和變數。

修飾類

當用final修飾一個類時,表明這個類不能被繼承。也就是說,如果一個類你永遠不會讓他被繼承,就可以用final進行修飾。final類中的成員變數可以根據需要設為final,但是要注意final類中的所有成員方法都會被隱式地指定為final方法。

  在使用final修飾類的時候,要注意謹慎選擇,除非這個類真的在以後不會用來繼承或者出於安全的考慮,盡量不要將類設計為final類。

修飾方法

  使用final方法的原因有兩個。第一個原因是把方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率。在早期的Java實現版本中,會將final方法轉為內嵌調用。但是如果方法過於龐大,可能看不到內嵌調用帶來的任何效能提升。在最近的Java版本中,不需要使用final方法進行這些最佳化了。

  因此,如果只有在想明確禁止 該方法在子類中被覆蓋的情況下才將方法設定為final的。

  註:類的private方法會隱式地被指定為final方法。

修飾變數

  修飾變數是final用得最多的地方,也是本文接下來要重點闡述的內容。首先瞭解一下final變數的基本文法:

  對於一個final變數,如果是基礎資料型別 (Elementary Data Type)的變數,則其數值一旦在初始化之後便不能更改;如果是參考型別的變數,則在對其初始化之後便不能再讓其指向另一個對象。


String類型我們也做一個補充總結:

String不是基本類型,而是物件類型,並且,其內部喲一個final的char數組,因此String的方法中不提供修改String中內容字元的方法。即便是subString、replace等看似修改了String的方法,其實只是返回了一個新的String對象,而原數組沒有變化。這樣做的目的有效能的、安全執行緒諸多方面的考慮,以後我會專門開一個文章講這個。



Java的final關鍵字與String的內部比較方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.