java String類常量池分析及"equals"和"==”區(qū)別詳細介紹
java "equals"和"==”異同
首先簡單說一下“equal”和“==”
==操作對于基本數(shù)據(jù)類型比較的是兩個變量的值是否相等,
對于引用型變量表示的是兩個變量在堆中存儲的地址是否相同,
即棧中的內容是否相同
equals操作表示的兩個變量是否是對同一個對象的引用,
即堆中的內容是否相同。
綜上,==比較的是2個對象的地址,而equals比較的是2個對象的內容。
再簡單介紹一下String類
String類 又稱作不可變字符序列
String使用private final char value[]來實現(xiàn)字符串的存儲,也就是說String對象創(chuàng)建之后,就不能再修改此對象中存儲的字符串內容。String類有一個特殊的創(chuàng)建方法,就是使用""雙引號來創(chuàng)建。例如new String("123")實際創(chuàng)建了2個String對象,一個是"123"通過""雙引號創(chuàng)建的,另一個是通過new創(chuàng)建的.只不過他們創(chuàng)建的時期不同,一個是編譯期,一個是運行期。java對String類型重載了+操作符,可以直接使用+對兩個字符串進行連接。運行期調用String類的intern()方法可以向String Pool中動態(tài)添加對象。
區(qū)分兩種創(chuàng)建String對象的方法“”和new()
String是一個特殊的包裝類數(shù)據(jù)??梢杂茫?br />
String str1 = new String("123");
String str2 = "123";
兩種的形式來創(chuàng)建
第一種是用new()來新建對象的,它會在存放于堆中。每調用一次就會創(chuàng)建一個新的對象。(實際是兩個正如上文所說,但是在常量池中存在“123”后就不會再在常量池中創(chuàng)建新的“123”)
第二種是先在棧中創(chuàng)建一個對String類的對象引用變量str,然后通過符號引用去字符串常量池里找有沒有"abc",如果沒有,則將"abc"存放進字符串常量池,并令str指向”abc”,如果已經(jīng)有”abc”則直接令str指向“abc”。
這時我們應該注意
一方面,第一種寫法有利與節(jié)省內存空間.同時它可以在一定程度上提高程序的運行速度,因為JVM會自動根據(jù)棧中數(shù)據(jù)的實際情況來決定是否有必要創(chuàng)建新對象。而對于String str = new String("123");的代碼,則一概在堆中創(chuàng)建新對象,而不管其字符串值是否相等,是否有必要創(chuàng)建新對象,從而加重了程序的負擔。另一方面,我們在使用諸如String str = "123";的格式定義類時,總是想當然地認為,創(chuàng)建了String類的對象str。
對象可能并沒有被創(chuàng)建!而可能只是指向一個先前已經(jīng)創(chuàng)建的對象。只有通過new()方法才能保證每次都創(chuàng)建一個新的對象。
請看下列實例
package testString;
public class testString
{
public static void main(String[] args)
{
String a = "123";
String b = "123";
System.out.println(a==b);
System.out.println(a.equals(b));
System.out.println("------------------------------------------");
/**
* true
* true
* 此處創(chuàng)建一個字符串"123"儲存在常量池中
* 因為"123"儲存在常量區(qū),并且唯一,即兩個String引用a和b所的地址相同所以a==b為true
* 并且兩個引用在所指對象在堆中的內容相同所以a.equals(b)為true
*/
String c = new String("1234");
String d = new String("1234");
System.out.println(c==d);
System.out.println(c.equals(d));
System.out.println("------------------------------------------");
/*
* false
* true
* 此處創(chuàng)建三個字符串“1234”,一個在常量池中,兩個通過new儲存在堆中
* 因為c和d此時指向的是堆中的兩個String對象,所以地址不同 c==d為false
* 但是c與d堆中內容相同所以c.equals(d)為true
*/
String e = "a1";
String f = "a"+1;
System.out.println(e==f);
System.out.println(e.equals(f));
System.out.println("------------------------------------------");
/**
* true
* true
* 此處創(chuàng)建“a1”“a”2個字符串其中“a1”“a”他們兩個均在常量池中,你可能會問+是個運算符重載么?
* 是的,java自己有一定的運算符重載但是你沒法使用定義自己的運算符重載,和c++不同,String f = "a"+1;
* 這句會被編譯器做成 String f=“a1”;這與我們講到的第一種情況相同,不再贅述。
* 編譯器之所以這么做是因為他在編譯時就能夠確定
*/
String g = "gh";
String hh = "h";
String h = "g" + hh ;
System.out.println(g==h);
System.out.println(g.equals(h));
System.out.println("------------------------------------------");
/**
* false
* true
* 與上面不同的是這里的h在編譯時不能確定(編譯器是這樣認為的),所以h所指的對象在運行時確定儲存在堆中,
* 所以g==h為true而g.equals(h)為false
*/
}
}
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關文章
SpringBoot集成Redisson操作Redis的實現(xiàn)方法
Redisson是一個用于Java的Redis客戶端,它提供了在分布式環(huán)境下操作Redis數(shù)據(jù)庫的簡單、高效的方式,本文主要介紹了SpringBoot集成Redisson操作Redis的實現(xiàn)方法,具有一定的參考價值,感興趣的可以了解一下2024-03-03
Spring中property-placeholder的使用與解析詳解
本篇文章主要介紹了Spring中property-placeholder的使用與解析詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
解決SpringMVC Controller 接收頁面?zhèn)鬟f的中文參數(shù)出現(xiàn)亂碼的問題
下面小編就為大家分享一篇解決SpringMVC Controller 接收頁面?zhèn)鬟f的中文參數(shù)出現(xiàn)亂碼的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
Java C++解決在排序數(shù)組中查找數(shù)字出現(xiàn)次數(shù)問題
本文終于介紹了分別通過Java和C++實現(xiàn)統(tǒng)計一個數(shù)字在排序數(shù)組中出現(xiàn)的次數(shù)。文中詳細介紹了實現(xiàn)思路,感興趣的小伙伴可以跟隨小編學習一下2021-12-12
java WebSocket實現(xiàn)聊天消息推送功能
這篇文章主要為大家詳細介紹了java WebSocket實現(xiàn)聊天消息推送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07
linux下用renameTo方法修改java web項目中文件夾名稱的實例
下面小編就為大家?guī)硪黄猯inux下用renameTo方法修改java web項目中文件夾名稱的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06
SpringBoot中l(wèi)ogback日志保存到mongoDB的方法
這篇文章主要介紹了SpringBoot中l(wèi)ogback日志保存到mongoDB的方法,2017-11-11

