JAVA中“相等性比較”的實現技巧
來源:用戶上傳
作者:
摘要:本文主要研究JAVA語言中如何進行基本類型和引用類型數據的“相等性比較”.通過介紹JAVA程序運行時的內存、運算符==、方法equals知識,解析String類中equals源碼,研究具體程序的運行過程,闡明各類數據“相等性比較”的實現技巧.
關鍵詞:相等性比較;常量池;==;equals();方法重寫
中圖分類號:TP312 文獻標識碼:A 文章編號:1673-260X(2019)04-0053-02
1 引言
Java語言具有面向對象、跨平臺、多線程等優良特性,在歷年TIOBE世界編程語言排行中多居榜首,是世界上使用范圍最廣的編程語言之一[1].在Java編程過程中,有時需要對數據是否相等進行比較.Java語言的數據類型分兩大類:基本類型、引用類型.基本類型的變量中存儲的是具體的數據值,變量比較大小時比較的是具體數據值;引用類型變量中存儲的是對象的引用,在根類Object類的toString()方法中聲明為:getClass().getName() + "@" + Integer.toHexString(hashCode()),各子孫類可以根據需要將其改寫.
2 知識介紹
2.1 Java程序運行時的內存
Java程序運行時,需要占用內存空間,每一片區域都有特定的處理數據方式和內存管理方式[2].Java程序運行時的內存區域主要劃分為:棧區、堆區、靜態數據區、代碼區等5個區域,現主要介紹前三個區域.
(1)棧區(VM Stack):虛擬機棧中存放了一個個棧幀,當程序執行一個方法時,就入創建一個棧幀并壓入棧中,一個棧幀中主要包括有局部變量表、操作數棧等,方法執行完畢后,此棧幀從VM Stack中移除.
(2)堆區(Heap):存放所有new出來的東西,如對象實例、數組等.
(3)方法區(Method Area):用于存放被虛擬機加載的類信息、常量、靜態常量等,運行時常量池也在方法區中.常量池中所有相同的常量被合并,只占用一個空間.
(4)本地方法棧(Native Method Stack).
(5)程序計數器(Program Counter Register).
2.2 Java中如何比較數據是否相等
方法一:使用操作符“==”,比較兩個操作數在棧區的值是否相等.若為基本類型數據,比較的是具體的數據值是否相等[3];若為引用類型數據,比較的是兩個對象的引用值,當且僅當兩個對象的引用值相同時,即是指向堆區或方法區的同一個對象實體時,結果為true.
方法二:使用equals()方法[4].根結點類Object類的equals(Object obj)方法體為:return (this == obj); 各子孫類可以根據需要修改.
2.3 方法重寫
日常生活中,我們比較兩個對象是否相同,主要比較的是兩個對象的主要屬性值是否相同.比如說我們的書丟失了,需要買一本一樣的書,意思是買一本ISBN相同的書即可,也就是說出版社、作者名、書名、版次、價格等信息相同即可,不是非得就是原來的那本書.
具體類可以制定相應的規則用于比較兩個此類對象是否相等,一般來講,這種規則的制定通過重寫父類中的equals方法來實現.在此,我們來研究String對象的比較規則.
2.4 String類源碼解析
解析:每一個String對象內部都有一個重要的成員變量:char類型的數組value[],用于存放字符串對象所對應的字符序列.
解析:String對象的equals方法,在兩種情況下方法返回值為true:1、當前對象與形參對象的引用值相同,即指向同一對象實例時,返回值為true.2、當形參為字符串對象,且當前對象與形參對象的成員變量value數組的長度相同,則依次比較兩個value數組中每一個數組元素的值,若所有字符數組元素都相同,則返回值為true.在前面已知,字符串對象的value數組中存放的是字符串對象所對應的字符序列.簡而言之,若當前字符串對象與形參字符串對象的字符序列相同,則返回為true.
3 程序舉例
執行代碼3、4后,JVM在棧區開辟空間i1、i2、i3、s1、s2、s3、s4.
執行代碼5、6、7后,棧區空間i1被賦值88、i2被賦值10000、i3被賦值88.
執行代碼8,輸出“i1==i2”的比較結果,比較棧區i1與i2空間的整型常量值是否相等,不相等,故輸出為false.
執行代碼9,輸出“i1==i3”的比較結果,比較棧區i1與i3空間的整型常量值是否相等,相等,故輸出為true.
執行代碼10,JVM檢查常量池中是否已存在“巢湖學院”字符串常量,若已存在,則直接讓棧區s1指向常量池中的該對象,當前程序中,常量池中現在沒有“巢湖學院”這個字符串常量,故在常量池中開辟一個新的空間存放此字符串常量,并讓棧區s1指向該對象.
執行代碼11,JVM檢查常量池中是否已存在“巢湖學院”字符串常量,因已存在,所以直接讓棧區s2指向該對象.
執行代碼12,JVM在堆區創建一個新的字符串對象,并讓棧區s3指向該對象.
執行代碼13,JVM在堆區創建一個新的字符串對象,并讓棧區s4指向該對象.
執行代碼14,JVM在比較棧區s1和s2的引用值是否相等,即是否指向同一個對象,因為s1與s2均指向常量池的同一個“巢湖學院”字符串常量對象,故輸出為true.
執行代碼15,JVM在比較棧區s1和s2所指向對象的value數組元素是是否相同,即字符串對象的字符序列是否相同,是,故輸出為true.
執行代碼16,JVM在比較棧區s3和s4的引用值是否相等,即是否指向同一個對象,因為s3與s4分別指向堆區的兩個不同字符串對象,故輸出為false.
執行代碼17,JVM在比較棧區s3和s4所指向的對象的value數組元素是否相同,即堆區兩個字符串對象的字符序列是否相同,是,故輸出為true.
4 結語
通過本文的源碼解析與程序執行過程中的內存分析,我們知道,在JAVA中實現“相等性比較”的技巧及相應原理.運用運算符“==”比較時,基本類型數據比較的是數據值[3,5],引用類型數據比較的是引用值;類可以通過重寫equals方法來制定本類對象是否相等的規則.
參考文獻:
〔1〕李小榮,疏志年,陳麗萍,程軍.用軟件工程指導Java程序設計[J].福建電腦,2015,31(12):66+150.
〔2〕海子.JVM的內存區域劃分[EB/OL].http://www.cnblogs.com/dolphin0520/p/3613043.html;2014 -05-29.
〔3〕黃海東.JAVA中實現“相等”比較的深入分析[J].湖北第二師范學院學報,2015,32(02):31-35.
〔4〕錢宇虹.論Java對象的比較技巧[J].軟件工程師,2010(08):50-53.
〔5〕田春婷.Java對象的比較方式[J].電腦知識與技術,2014,10(34):8163-8164.
轉載注明來源:http://www.hailuomaifang.com/1/view-14841795.htm