提到==與equals的區別,這就必須先回顧一下jvm記憶體的分配機制
==和equals無非比較兩個基本資料型別或者物件型別
八種基本型別:
基本型別 | 大小 | 預設值 | 封裝類 |
byte | 1 | 0 | Byte |
short | 2 | 0 | Short |
int | 4 | 0 | Integer |
long | 8 | 0L | Long |
float | 4 | 0.0f | Float |
double | 8 | 0.0d | Double |
boolean | false |
Boolean |
|
char | 2 | \u0000(null) | Character |
基本資料型比較:==
這八種資料型別儲存在棧中,他們是作為常量在方法區中的常量池裡面以HashSet策略儲存起來的,值一樣的常量只有一個地址。我們用==比較是沒問題的,String是一個比較特殊的物件型別,他不用new就可以建立一個物件因此他也類似於基本資料型別儲存起來,可以用==比較,當然如果通過new的方式建立的物件就必須通過下面物件型別方式的比較。
int a=1; int b=1; System.out.println(a==b); //結果為ture Integer c=128; Integer d=128; System.out.println(c==d);//結果為false
String str="123";
String str2="123";
System.out.println(str == str2);//結果為ture
是不是覺得很奇怪,上面明明說基本資料型別只要值一樣存放的地址也一樣為什麼到Integer變了呢。 其實是這樣的Integer的範圍區間在 -128~+127之間,那麼我們讓他等於128超出了它的範圍他就無法在常量池中(常量池會初始化-128~+127的所有Integer物件)獲取到該值得地址,就會去new一個Integer型別的物件,因此地址不同比較結果返回了false就不難理解了。(這裡涉及到了java自動裝箱和拆箱)
物件資料型別比較:equals
物件資料型別儲存在堆中,棧中生成對應的引用,當我們建立一個物件後,在後續得使用中都是使用引用來操作物件,所以物件即便所有的屬性都相等,但在棧中存放的地址不同使用==比較也會返回false
其實我們點進equals方法內部可以看到他用的還是==比較,那麼他怎麼解決物件之間的比較呢? 重寫,我們可以一個class中重寫equals方法以此來達到比較物件的屬性是否相等。其中String 自己已經重寫好了equals方法