變量之間賦值的傳遞、方法的參數(shù)傳遞,值傳遞、引用傳遞?

關(guān)于java程序運行時各種變量在內(nèi)存的存儲知識先看這里》》


變量賦值:

對于基本數(shù)據(jù)類型變量:即int, short, long, byte, float, double, boolean, char類型的變量。這種類型變量在內(nèi)存中直接存放數(shù)據(jù)。變量之間賦值如int a=b;直接傳數(shù)據(jù)。a++,不影響b的數(shù)據(jù)。

對象變量:對象變量在內(nèi)存中存放的是引用。這個引用值指向堆中的對象。Object c=b;傳的是引用值,他們指向同一個堆對象。

如上圖,age是int變量,具體數(shù)據(jù)值如9,就放在那里,而owner是對象變量,它放的是引用,指向堆里owner對象。

下兩圖是方法調(diào)用時在棧幀里的局部變量表里的變量和參數(shù),圖示示例了兩種引用對象的方式。

(詳細(xì)java程序運行時的棧幀內(nèi)存結(jié)構(gòu)看這里》》)


此圖示例了通過句柄池引用方式指向堆對象的方式。

此圖示例了直接指向堆中對象的方式

兩種方式各有優(yōu)勢,第一種方式在對象被GC遷移時只需改變句柄池中的實例指針即可,而不用改變reference引用本身的值。第二種方式就是訪問速度快。目前HotSpot虛擬機就采用的第二種方式。

下面用個例子來說明:

下面是個Dog類,用來測試時產(chǎn)生對象,進(jìn)行引用傳遞

Dog類

mName和mYear是類的實例變量

下面是傳遞變量測試類,其中也有變量賦值測試然后打印出來

主測試類

結(jié)果:

第1行和第2行對比:基礎(chǔ)類型變量之間賦值傳值,互相不影響;對象變量之間賦值傳引用,mainDog和mainDog2指向同一個堆內(nèi)的對象。mainDog2把對象名字改變后,mainDog打印出來也是改變后的名字。

第2、3、4、5行之間對比:方法參數(shù)的傳遞,基礎(chǔ)型參數(shù)變量傳值,和外面的基礎(chǔ)類型實例變量互不影響。方法的對象類型參數(shù)傳遞時傳引用,和外面的實例變量引用值相同,指向堆內(nèi)同一個對象。此時堆內(nèi)只有一個dog。

第5、6、7行之間對比:方法內(nèi)的對象參數(shù)或?qū)ο缶植孔兞扛淖円弥禃r,不影響外面的對象實例變量。此時方法內(nèi)mainDog對象參數(shù)變量指向的堆對象和實例對象變量mainDog指向的堆對象不同。堆內(nèi)曾有過2個dog。

如何 讓對象變量之間賦值傳值而不是引用呢?

Dog dog=new dog();

Dog dog2=dog;

如要達(dá)到dog2是個獨立的堆對象,但屬性要與dog一模一樣;

Dog dog2=dog.clone();需要類實現(xiàn)clone接口;

設(shè)計模式中有個原型模式,就是clone;原型模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容