Java方法參數(shù)傳遞機(jī)制原理解析
這篇文章主要介紹了Java方法參數(shù)傳遞機(jī)制原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
Java方法中如果聲明了形參,在調(diào)用方法時(shí)就必須給這些形參指定參數(shù)值,實(shí)際傳進(jìn)去的這個(gè)值就叫做實(shí)參。
這就涉及到Java中的參數(shù)傳遞機(jī)制,值傳遞。
基本數(shù)據(jù)類型
基本數(shù)據(jù)類型,值傳遞的體現(xiàn)是數(shù)值的傳遞。
public class TransferTempTest { public static void main(String[] args) { //基本數(shù)據(jù)類型參數(shù)傳遞 TransferTempTest test = new TransferTempTest(); int num1 = 10; int num2 = 20; System.out.println("進(jìn)行交換前:"); System.out.println("num1 = " + num1 + ",num2 = " + num2); test.swap(num1, num2); System.out.println("交換之后:"); System.out.println("num1 = " + num1 + ",num2 = " + num2); } public void swap(int a, int b) { int temp = a; a = b; b = temp; System.out.println("交換過(guò)程中:"); System.out.println("num1 = " + a + ",num2 = " + b); } }
//運(yùn)行結(jié)果 進(jìn)行交換前: num1 = 10,num2 = 20 交換過(guò)程中: num1 = 20,num2 = 10 交換之后: num1 = 10,num2 = 20
整個(gè)過(guò)程的內(nèi)存圖演示:
如圖所示:
- 在堆內(nèi)存中創(chuàng)建 TransferTempTest類型的對(duì)象,假設(shè)此時(shí)地址值時(shí)0x1177(只是假設(shè)),并讓棧內(nèi)存中的引用變量test存儲(chǔ)0x1177,指向該對(duì)象。
- 在棧內(nèi)存中聲明兩個(gè)變量num1和num2,并為他們賦值10和20。這時(shí)可以看到打印的結(jié)果為:num1 = 10,num2 = 20
- 程序繼續(xù)向下,進(jìn)入swap方法,首先在棧區(qū)聲明兩個(gè)變量a和b,他們都是形參,這時(shí)將num1和num2的值分別傳入,此時(shí)如藍(lán)色字體所顯示,a=10,b=20。
- 接著還是在棧區(qū)聲明一個(gè)名為temp的變量,這時(shí)執(zhí)行的交換過(guò)程是在swap方法中,交換的變量其實(shí)是num1和num2的拷貝值,所以方法內(nèi)打印:num1 = 20,num2 = 10
- 最后,退出這個(gè)方法,局部變量銷毀,發(fā)現(xiàn)其實(shí)一頓操作,原先的值根本就沒(méi)有改變,打印結(jié)果和原先一樣:num1 = 10,num2 = 20
引用數(shù)據(jù)類型
基本數(shù)據(jù)類型,值傳遞的體現(xiàn)是地址值的傳遞。
public class TransferTempTest { public static void main(String[] args) { //引用類型參數(shù)傳遞 DataTemp data = new DataTemp(); data.a = 2; data.b = 4; System.out.println("進(jìn)行交換前:"); System.out.println("data.a = " + data.a + ",data.b = " + data.b); data.swapClass(data); System.out.println("進(jìn)行交換后:"); System.out.println("data.a = " + data.a + ",data.b = " + data.b); } } class DataTemp { int a; int b; public void swapClass(DataTemp data) { int temp = data.a; data.a = data.b; data.b = temp; System.out.println("交換過(guò)程中:"); System.out.println("data.a = " + data.a + ",data.b = " + data.b); } }
//運(yùn)行結(jié)果 進(jìn)行交換前: data.a = 2,data.b = 4 交換過(guò)程中: data.a = 4,data.b = 2 進(jìn)行交換后: data.a = 4,data.b = 2
整個(gè)過(guò)程的內(nèi)存圖顯示:
如圖所示:
- 在堆內(nèi)存中創(chuàng)建DataTemp類型的對(duì)象,并讓棧內(nèi)存中的引用變量data存儲(chǔ)0x7788(假設(shè)地址值),指向該對(duì)象,實(shí)例變量a和b的初始值都是0。
- 讓data.a=2,data.b=4,如藍(lán)色字體顯示,這時(shí)打?。篸ata.a = 2,data.b = 4
- 進(jìn)入swapClass方法,首先在棧區(qū)聲明形參變量data,將原來(lái)的data的地址值傳入,紅黑兩個(gè)data不是同一個(gè)??!,紅色data只是黑色data的拷貝值,且拷貝的是地址值。這時(shí)兩個(gè)data指向同一片堆區(qū)內(nèi)存,如紅色箭頭顯示。
- 接著還是在棧區(qū)聲明一個(gè)名為temp的變量,參與交換操作,這時(shí)操作的是堆區(qū)的數(shù)據(jù),所以方法里顯然打?。篸ata.a = 4,data.b = 2
- 最后,退出這個(gè)方法,局部變量銷毀,執(zhí)行的交換過(guò)程雖然是在swapClass方法中,但引用變量傳入形參傳遞的是地址值,意味著,這時(shí)的交換操作直接對(duì)堆區(qū)對(duì)象生效,所以最終交換成立:data.a = 4,data.b = 2
綜合練習(xí)
package com.my.pac05; public class TransferTest { public static void main(String[] args) { TransferTest test = new TransferTest(); test.first(); } public void first() { int i = 5; Value v = new Value(); v.i = 25; second(v, i); System.out.println(v.i); } public void second(Value v, int i) { i = 0; v.i = 20; Value val = new Value(); v = val; System.out.println(v.i + " " + i); } } class Value { int i = 15; }
//運(yùn)行結(jié)果 15 0 20
整個(gè)過(guò)程的內(nèi)存圖顯示:
總結(jié)
- 方法不能修改基本數(shù)據(jù)類型的參數(shù),他們改變的僅僅是他們的拷貝。
- 方法可以改變對(duì)象參數(shù)的狀態(tài),因?yàn)榉椒梢酝ㄟ^(guò)對(duì)象引用的拷貝修改對(duì)象狀態(tài)。
- 方法不能讓對(duì)象參數(shù)引用一個(gè)新的對(duì)象,方法得到的永遠(yuǎn)都是拷貝值。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于spring.factories的常用配置項(xiàng)說(shuō)明
這篇文章主要介紹了關(guān)于spring.factories的常用配置項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07springboot下實(shí)現(xiàn)RedisTemplate?List?清空
我們經(jīng)常會(huì)使用Redis的List數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)一系列的元素,當(dāng)我們需要清空一個(gè)List時(shí),可以使用RedisTemplate來(lái)實(shí)現(xiàn),本文就來(lái)詳細(xì)的介紹一下如何實(shí)現(xiàn),感興趣的可以了解一下2024-01-01Android中Socket通信的實(shí)現(xiàn)方法概述
這篇文章主要介紹了Android中Socket通信的實(shí)現(xiàn)方法,很有實(shí)用價(jià)值,需要的朋友可以參考下2014-08-08springboot學(xué)習(xí)之Thymeleaf模板引擎及原理介紹
本文主要介紹一下SpringBoot給我們推薦的Thymeleaf模板引擎,這模板引擎呢,是一個(gè)高級(jí)語(yǔ)言的模板引擎,他的這個(gè)語(yǔ)法更簡(jiǎn)單而且功能更強(qiáng)大,對(duì)springboot?Thymeleaf模板引擎相關(guān)知識(shí)感興趣的朋友一起看看吧2022-02-02淺談maven的jar包和war包區(qū)別 以及打包方法
下面小編就為大家分享一篇淺談maven的jar包和war包區(qū)別 以及打包方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2017-11-11用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM
這篇文章主要介紹了用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM的方法,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot,感興趣的朋友可以了解下2021-04-04