自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

對象比較在Java中的實(shí)現(xiàn)淺析

開發(fā) 后端
在Java語言中,主要可以利用==運(yùn)算符(兩個(gè)等號(hào))和equal函數(shù)來對對象進(jìn)行比較。不過這兩個(gè)符號(hào)其實(shí)現(xiàn)的機(jī)制不同,本文將向你介紹對象比較在Java中的實(shí)現(xiàn)。

一、跟對象比較的幾個(gè)相關(guān)的概念。

為了更加審核的理解對象比較的含義以及多個(gè)比較方法之間的差異,筆者認(rèn)為讀者首先需要了解幾個(gè)相關(guān)的概念,或者說幾對關(guān)系。

一是類與對象的關(guān)系。類是具體的抽象,而對象是類的具體實(shí)現(xiàn)。這可能聽起來還是有點(diǎn)模糊。做一個(gè)形象的比喻,類就好像是用來制作塑料盒子的模具,只要將PVC料注入到這個(gè)模具中就可以生產(chǎn)對應(yīng)形狀的盒子。而對象就好像是生產(chǎn)出來的盒子。雖然模具同一個(gè),但是生產(chǎn)出來的盒子彼此之間仍然是不同的。一方面先天性就是不同的。因?yàn)楦鶕?jù)相對論可以說明世界上沒有兩個(gè)相同的東西。其次后天性的影響,也會(huì)導(dǎo)致其不同。如生產(chǎn)出來后,在兩個(gè)盒子上分別貼上不同的條碼,他們兩個(gè)就代表不同的盒子了。了解這個(gè)類與對象之間的關(guān)系,對于了解對象之間進(jìn)行比較,會(huì)有很大的幫助。

二是需要知道類與對象在內(nèi)存中的實(shí)際存儲(chǔ)情況。當(dāng)程序員定義一個(gè)類時(shí)(不含有靜態(tài)成員或者變量),一般不會(huì)在內(nèi)存中給其分配一個(gè)存儲(chǔ)結(jié)構(gòu)。而只有定義對象時(shí),才會(huì)在內(nèi)存中分配存儲(chǔ)結(jié)構(gòu)。當(dāng)利用同一個(gè)類定義不同的對象時(shí),系統(tǒng)會(huì)在內(nèi)存中為不同的對象創(chuàng)建不同的存儲(chǔ)結(jié)構(gòu)。也就是說,會(huì)對應(yīng)不同的內(nèi)存地址。雖然同一個(gè)類中定義出來的對象,其內(nèi)容可能相同(成員變量、成員方法等等都相同),但是其內(nèi)存中的地址仍然是不同的。

三是需要注意對象的復(fù)制問題。如果要?jiǎng)?chuàng)建幾個(gè)內(nèi)容相同的對象,即復(fù)制相同內(nèi)容的對象,現(xiàn)在主要有兩種方法。一是通過成員變量賦值來完成。如在根據(jù)同一個(gè)類創(chuàng)建對象時(shí),分別給與他們相同的初始化值。那么這兩個(gè)對象的內(nèi)容就是相同的。二是通過地址賦值來完成。即將第一個(gè)對象在內(nèi)存中的地址賦值給第二個(gè)對象。此時(shí)兩個(gè)對象名字雖然不同,但是他們卻指向內(nèi)存中的同一塊區(qū)域。此時(shí)就好像一個(gè)人有兩個(gè)名字,其實(shí)是同一個(gè)人。所以這兩個(gè)對象內(nèi)容也就相同了。

二、利用==運(yùn)算符與equals方法來比較對象。

在Java語言中,主要可以利用==運(yùn)算符(兩個(gè)等號(hào))和equal函數(shù)來對對象進(jìn)行比較。不過這兩個(gè)符號(hào)其實(shí)現(xiàn)的機(jī)制不同。或者說,對于同樣的兩個(gè)對象,如果利用他們來進(jìn)行比較的話,往往會(huì)有不同的結(jié)果。如String是Java自定義的對象,其主要用來存儲(chǔ)字符串?dāng)?shù)據(jù)?,F(xiàn)在筆者利用如下語句定義了三個(gè)String對象。

String str1=new String(“welcome”); //創(chuàng)建一個(gè)對象,給利用單詞welcome初始化

String str2=new String(“welcome”); //創(chuàng)建一個(gè)對象,給利用單詞welcome初始化

String str3=str1; //創(chuàng)建一個(gè)對象,并利用對象str1的地址賦值

以上三個(gè)對象,顯而易見,其內(nèi)容都是相同的。但是利用這個(gè)兩種方式來對他們進(jìn)行比較的時(shí)候,往往會(huì)有不同的結(jié)果。如利用==(兩個(gè)等號(hào))比較符號(hào)來進(jìn)行比較,str1==str2,最后返回的結(jié)構(gòu)是false,也就是他們是不相同的對象??墒侨绻容^str1==str3對象,則最后返回的結(jié)果卻是true。但是利用equal函數(shù)來比較,則返回的結(jié)果是相同的。為什么對象的內(nèi)容相同,它們返回的結(jié)果卻是不同的呢?

要回答這個(gè)問題,就需要大家先回顧一下筆者上面談到的幾對關(guān)系。首先,對象str1與對象str2的關(guān)系,就好像是同一個(gè)模具出來的兩個(gè)盒子,他們從外觀看起來雖然相同,但是通過放大鏡或者其他精密儀器仍然可以看到,兩個(gè)盒子是不同的東西。這兩個(gè)對象雖然內(nèi)容相同,但是其在內(nèi)存中分配的地址不同。也就是說,是同一個(gè)模具出來的外觀看起來相同的不同的盒子。而對象str1與對象str3就好像是一個(gè)人有兩個(gè)名字。雖然名字不同,但是實(shí)際上是同一個(gè)人。這主要是因?yàn)樗麄兊纳矸葑C號(hào)碼相同。其實(shí)這個(gè)身份證號(hào)碼就好像是內(nèi)存中發(fā)配的地址,而對象名字就好象是人的名字。一個(gè)人可以有好幾個(gè)名字(一個(gè)對象有好幾個(gè)名字),但是其身份證號(hào)碼只有一個(gè)(內(nèi)存分配地址只有一個(gè))。在上面的語句中,通過str3=str1,其實(shí)現(xiàn)的功能,并不是將對象str1的值賦值給對象str3。而是將對象str1在內(nèi)存中的地址賦值給了對象str1(就好像是將一個(gè)人的身份證號(hào)碼復(fù)制給了另外一個(gè)人)。所以從本質(zhì)上說,str3并不是一個(gè)新建立的對象。因?yàn)橄到y(tǒng)并沒有在內(nèi)存中為其分配一個(gè)新的存儲(chǔ)區(qū)域(即并沒有創(chuàng)造一個(gè)新的人),而只是好像給對象另外取了一個(gè)別名。

 所以說,在對象比較的時(shí)候,需要搞清楚一個(gè)問題。即現(xiàn)在要比較的是他們的內(nèi)容還是在內(nèi)存中指向的地址。一般來說,內(nèi)容相同不一定他們在內(nèi)存中指向的地址也是相同的。而不同的對象在內(nèi)存中若指向同一個(gè)地址,則他們的內(nèi)容肯定是相同的(因?yàn)樗麄儗?shí)際上就是同一個(gè)對象)。而==(兩個(gè)等號(hào))運(yùn)算符與equal函數(shù)就是運(yùn)來比較這兩塊內(nèi)容的。其中==運(yùn)算符是用來比較內(nèi)存中的地址是否相同,即比較它們的身份證號(hào)碼是否相同。而equal函數(shù)則只比較他們的內(nèi)容。如果他們的內(nèi)容相同,即使身份證號(hào)碼不相同(內(nèi)存中的地址不同),這個(gè)函數(shù)也人們他們是相同的,會(huì)返回TRUE值。這就是這個(gè)兩個(gè)對象比較方式的最大不同?;蛘哒f,他們在對對象進(jìn)行比較時(shí),出發(fā)點(diǎn)不同。一個(gè)比較對象名字所指向的內(nèi)存地址是否相同,另外一個(gè)比較的時(shí) 對象名字所指向的存儲(chǔ)模塊中的內(nèi)容是否相同。所以他們就會(huì)返回不同的結(jié)果。

三、慎用內(nèi)存地址賦值。

在實(shí)際工作中,筆者提醒程序開發(fā)人員,要慎用這種str3=str1內(nèi)存地址的賦值形式。其實(shí),利用這種形式來創(chuàng)建對象,其實(shí)根本沒有創(chuàng)建一個(gè)新的對象。而只是將兩個(gè)對象同時(shí)指向內(nèi)存中的同一個(gè)存儲(chǔ)區(qū)域。由于他們實(shí)際上是同一個(gè)對象,為此通過其中一個(gè)對象修改了對象的內(nèi)容,那么另外一個(gè)對象名字調(diào)用的對象其也會(huì)受到影響。也就是說,它們相互之間缺乏獨(dú)立性。為此在創(chuàng)建對象的時(shí)候,如果沒有特殊的必要,最好為不同的對象名創(chuàng)建不同的實(shí)體對象。而不要將多個(gè)對象名指向同一個(gè)對象,這在開發(fā)應(yīng)用程序的時(shí)候容易導(dǎo)致對象內(nèi)容被無意中修改,從而導(dǎo)致應(yīng)用程序結(jié)果出錯(cuò)。

最后筆者需要提醒的是,在選擇對象比較方式的時(shí)候,要了解==運(yùn)算符與euqal函數(shù)之間的差異。如果只是想比較對象的內(nèi)容是否相同,則只需要使用equal函數(shù)即可。但是如果要比較他們是否是同一個(gè)對象,即在內(nèi)存中是否指向同一個(gè)存儲(chǔ)區(qū)域,則需要使用==運(yùn)算符。在實(shí)際應(yīng)用的過程中,千萬不能夠張冠李戴。否則的話,很容易導(dǎo)致相反的結(jié)果。特別是將他們返回的值當(dāng)作條件判斷語句時(shí),更加需要謹(jǐn)慎。因?yàn)榇藭r(shí)如果選擇的方法錯(cuò)誤,則最后產(chǎn)生的結(jié)果往往是相反的。所以在對象進(jìn)行比較時(shí),跟變量的比較有很大的差異。在對象的比較上,程序員要謹(jǐn)慎行事。最根本的一點(diǎn)就是要搞清楚,到底比較的是什么東西,是對象內(nèi)部的存儲(chǔ)內(nèi)容還是在對象名字與內(nèi)存之間的關(guān)聯(lián)關(guān)系(對象內(nèi)存地址)。搞清楚這一點(diǎn)后,那么到底選擇采用哪種方式來進(jìn)行比較也就引刃而解了。

 

【編輯推薦】

  1. Java對象的強(qiáng)、軟、弱和虛引用
  2. Java對象的序列化和反序列化實(shí)踐
  3. 深入Java對象及元素的存儲(chǔ)區(qū)域
  4. Java對象序列化使用基礎(chǔ)
  5. 使用Java截取字符串的方法
責(zé)任編輯:佚名 來源: IT專家網(wǎng)
相關(guān)推薦

2009-06-30 09:37:02

對象比較Java

2024-01-29 00:57:20

GuavaJava拷貝

2021-03-06 14:22:39

池化對象類庫

2011-12-16 14:34:22

Java

2009-09-29 16:11:45

Hibernate實(shí)現(xiàn)

2011-04-13 15:03:25

NATlP

2010-02-05 15:32:33

Java內(nèi)部類

2012-02-29 09:32:01

Java

2011-12-29 15:35:39

Web

2021-07-15 08:58:16

Spring對象引用

2023-10-10 10:02:32

2009-09-07 14:41:48

GridView展開與

2021-07-27 22:56:00

JavaScript編程開發(fā)

2009-09-28 09:35:10

Hibernate實(shí)現(xiàn)實(shí)體對象延遲加載

2009-07-10 16:27:29

Eclipse和MyE

2017-05-24 09:43:42

2011-06-19 08:59:59

錨文本

2011-12-25 15:35:05

ibmdwJavaC++

2009-06-16 15:20:48

ApplicationJSP程序

2010-01-25 09:57:39

C++函數(shù)參數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)