淺析java中String型別中“==”與“equal”的區別
一、前言
1.1、首先很多人都知道,String中用“==”比較的是地址,用equals比較的是內容,很多人對此用的是記憶法,通過記憶來加強此的引用,但是其真正的原理其實並不難,當我們真正明白其為什麼的時候,用起來也會更加靈活,更加有底氣(形容得不太好,朋友別見怪);
二相關知識的準備
- 型別常量池
- 執行時常量池
- 字串常量池
我們今天討論的主題是當然是字串常量池:
為什麼在這要把另外兩個常量池拿出說一下呢,首先小生我在網上或者cnds上看到很多人在爭論字串常量池是存在與方法區還是堆裡面,因此我在這裡面非常負責任的告訴各位讀者:
1、型別常量池,存放在方法區裡面,每個class檔案都有一個
3、字串常量池:存放在堆區裡面
而且字串常量池有一個特點:存放的常量唯一:三、 開始
3.1,情況一
public class Test2 { public static void main(String[] args) { String a ="張敬軒"; String b ="張敬軒"; System.out.println(a == b); System.out.println(a.equals(b)); } }
執行結果:
- true
- true
解釋:因為當我們String a = “張敬軒”;的時候,會在堆裡面的字串常量池裡面“搜尋”是否有“張敬軒”這個物件,
- 有:就會將“張敬軒這個物件的地址指向a”
- 沒有:就會在字串常量池裡面新建立一個“張敬軒”,然後就會把地址引用賦值給a
當再宣告String b = “張敬軒";和第一次宣告String = “張敬軒”;一樣,先”搜尋“,然後因為已經存在了”張敬軒“這個物件,那麼就不會再建立物件,而是將存在的”張敬軒“的地址引用賦值給b,所以
a和b的地址一樣,內容自然也一樣,所以兩個結果為true,不懂各位朋友懂沒懂?
3.2,情況二;
public class Test2 { public static void main(String[] args) { String a ="張敬軒"; String b = new String("張敬軒"); System.out.println(a == b); System.out.println(a.equals(b)); } }
結果是
false,true
解釋
String a = “張敬軒”;
已經解釋過了,是在堆裡面的字串常量池建立物件
String b = new String(“張敬軒”);
這個也是在堆區裡面建立物件,但是不是在字串常量池裡面建立物件
兩個不同的物件,地址自然不同,類容都是張敬軒,所以結果是false,true
3.3、情況三
public class Test2 { public static void main(String[] args) { String a = new String("張敬軒"); String b = new String("張敬軒"); System.out.println(a == b); System.out.println(a.equals(b)); } }
結果:false,true
解釋,因為new (“張敬軒”);表示在堆區的非字串常量池裡面建立了兩個不同的物件,兩次new就建立了兩個,所以地址是不同的,因此結果是false,true
3.4、情況四
public class Test2 { public static void main(String[] args) { String a = "張"+"敬軒"; String b = "張敬軒"; System.out.println(a == b); System.out.println(a.equals(b)); } }
結果是:true,true
解釋:String = “張敬” + ”軒“;
在編譯的時候就已經開始進行計算:這是Java編譯的優化機制,所以a指向的地址依舊是”張敬軒“;所以情況和前面的情況一一致,所以是true,true
(注意Java編譯優化機制只針對常量不針對變數 a = a+ b(這個是沒有優化機制的,關於Java編譯機制,各位小夥伴可以去百度瞭解一下))
3.5、情況五
public class Test2 { public static void main(String[] args) { String a = "張"; String b = "敬軒"; String c =a+b; String d = "張敬軒"; System.out.println(d == c); System.out.println(d.equals(c)); } }
結果:
解釋:因為a 和 b是變數,不存在什麼Java優化機制,而是將兩個c = a + b存放在的是堆區的非字元常量池裡面,所以是兩個不同的物件,自然為false,true
3.6、最後一種情況
public class Test2 { public static void main(String[] args) { String a = "張"; String b = "敬軒"; String c =(a+b).intern(); String d = "張敬軒"; System.out.println(d == c); System.out.println(d.equals(c)); } }
結果:
解釋:intern();方法是將堆區裡面的非字元常量池裡面的物件強行放到字元常量池裡面,因為字元常量池裡面對象的唯一性,如果字串常量池裡面已經有了和”張敬軒“一樣的物件,就會將其地址引用賦值給c,沒有就相當於建立一個(也就是和之前堆區裡面那個物件一樣的物件),有了的話,就會將原來有的那個“張敬軒”物件賦值給c,因為地址一樣,所以為true
總結:
== 比較的地址 (如果物件存在字串常量池,而且類容相同,那麼 == 返回的是true )
equal 比較的是內容 (內容相同返回便是true)(所以在以後的開發中一般是用equal比較字串的)
各位朋友如果有錯的及時評論區指出,謝謝大家的支援
到此這篇關於淺析java中String型別中“==”與“equal”的區別的文章就介紹到這了,更多相關java String型別 ==與equal內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!