陸續從0開始學習Java出於多掌握一門語言之後的路也會更寬,.NET和Java兼顧,雖然路還很艱難,但事在人爲。因爲Java和C#語法類似,因此關於一些很基礎的內容不會再重頭講,Java系列中全部文章都會基於我我的所看文章和博客以後的思考,有些會和C#語法進行對比,有些是全新的概念,講解完整個基礎系列,而後進入數據結構和深刻學習JVM,我都會詳細記錄,全部系列語法都是基於Java8,咱們開始吧。html
在Java中建立字符串四種方式,一是直接經過new運算符建立字符串,二是經過字符數組建立、三是經過提取字符數組建立、四是經過定義字符串變量建立,下面咱們來一一過下java
(1)new運算符建立字符串數組
String str = new String("Jeffcky"); System.out.println(str);
(2)字符數組建立String對象數據結構
char a[] = {'j', 'e', 'f', 'f', 'c', 'k', 'y'}; String str = new String(a); System.out.println(str);
(3)提取字符數組建立String對象學習
經過如上第一種方式直接經過new運算符獲取字符數組,經過new運算符建立字符串對象還有重載,以下:this
char a[] = {'j', 'e', 'f', 'f', 'c', 'k', 'y'}; String str = new String(a,0,4); System.out.println(str);
該重載方式第一個參數則是操做的字符數據,第二個參數是偏移量offset,也就是說從字符數組哪裏開始截取,第三個參數是count,也就是說咱們要讀取幾個字符。spa
(4)字符串常量引用賦值建立字符串code
這種方式也是咱們最經常使用建立字符串變量的方式,以下:htm
String str = "Jeffcky";
System.out.println(str);
判斷字符串是否相等在Java和C#中處理方式不同,接下來咱們將對比C#和Java中的處理方式。咱們首先來總體看看C#和Java中判斷方式的不一樣,以下爲C#對象
static void Main(string[] args) { string str1 = new string("Jeffcky"); string str2 = new string("Jeffcky"); Console.WriteLine(str1 == str2); Console.WriteLine(str1.Equals(str2)); Console.ReadKey(); }
接下來咱們再來看看Java中相同判斷方式:
public static void main(String[] args) {
String str1 = new String("Jeffcky"); String str2 = new String("Jeffcky"); System.out.println(str1 == str2); System.out.println(str1.equals(str2)); }
經過如上C#和Java中打印結果,想必咱們就知道了不一樣,在C#中==對於值類型直接判斷其值是否相等,而對於引用類型尤爲是字符串則重寫了Equals方法而直接比較字符串值,因此上述都打印出true,在C#中若想要比較引用類型地址是否相等,則使用ReferenceEquals方法,因此上述在C#中的演示代碼要想獲得和Java中處理結果,則演示代碼變成以下:
static void Main(string[] args)
{
string str1 = new string("Jeffcky"); string str2 = new string("Jeffcky"); Console.WriteLine(ReferenceEquals(str1, str2)); Console.WriteLine(str1.Equals(str2)); Console.ReadKey(); }
咱們反觀Java中經過new操做符建立的字符串進行「==」比較是爲false,這是因爲經過new運算符建立了兩個相同字符串對象的地址不同,因而可知:在Java中的==並非比較字符串的值,由於「==」僅僅只檢查兩個字符串的引用相等性,意味着它們是否引用相同的對象。若是將上述Java代碼進行以下修改,此時兩個字符串經過「==」比較則相等:
public static void main(String[] args) {
String str1 = "Jeffcky"; String str2 = "Jeffcky"; System.out.println(str1 == str2); System.out.println(str1.equals(str2)); }
咱們通過如上修改後,經過「==」判斷此時str1和str2指向堆上同一對象Jeffcky的地址,很差理解?那麼接下來咱們通過以下修改則一目瞭然
public static void main(String[] args) {
String str1, str2;
str1 = "Jeffcky"; str2 = "Jeffcky"; System.out.println(str1 == str2); System.out.println(str1.equals(str2)); }
咱們再來進行一行行解釋,第一行字符串str1和str2引用爲null,第二行在堆上建立名爲Jeffcky的對象,此時將引用地址賦值給str1,第三行在堆上已有相同對象的字符串,直接將引用地址賦值給str2,因此此時str1和str2的引用對象相等打印出true。接下來咱們再來看equals方法,最喜歡的則是在Java中可直接查看源碼,咱們看看equals方法實現,以下:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
從如上源碼不難看出:String類重寫從Object繼承的equals方法,此方法逐個字符地比較兩個字符串,而忽略它們的引用地址,也就是說若是長度且字符順序相等,則認爲它們相等。
上述咱們討論到字符串中的equals方法重寫了Object類中的equals方法,那麼Object類中的equals方法進行比較的邏輯又是怎樣的呢?咱們來看看以下代碼:、
import java.util.Objects; public class Main { public static void main(String[] args) { String string1 = "using objects equals"; String string2 = "using objects equals"; String string3 = new String("using objects equals"); System.out.println(Objects.equals(string1, string2)); System.out.println(Objects.equals(string1, string3)); System.out.println(Objects.equals(null, null)); System.out.println(Objects.equals(null, string1)); } }
對於上述打印結果,咱們結合Object類中的equals源碼來分析,以下:
public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }
由此咱們得出結論:Object類中equals爲靜態方法,首先使用它們的地址比較它們,即「==」判斷,若是兩個字符串相等,則該方法返回true。同時若是兩個參數都爲null,則返回true,若是隻有一個參數爲null,則返回false。不然,它只是調用傳遞的參數類型的類的equals方法,上述則是String的類equals方法。 此方法區分大小寫,由於它在內部調用String類的equals方法。
本文咱們詳細介紹了Java中關於字符串的比較,可能和我同樣的初學者若是不是很瞭解內部實現的話會存在使用誤區,對於字符串判斷相等應該使用equals方法而不是「==」或者使用Object類的靜態方法equals(由於其內置會調用對象的equals方法),由於「==」是比較引用是否相等(這裏結論不太準確,更多詳細信息請參考《http://www.javashuo.com/article/p-hviquzcp-km.html》),固然對於值類型使用「==」毫無疑問沒毛病。