Java 中的值傳遞

其實 Java 中是只存在值傳遞的,不存在引用傳遞。因為我們大多數(shù)人是從 C 語言入門撬讽,而 C 語言中是存在引用傳遞的,所以很容易在 Java 中混淆吼过。

你還在為開發(fā)中頻繁切換環(huán)境打包而煩惱嗎锐秦?快來試試 Environment Switcher 吧!使用它可以在app運行時一鍵切換環(huán)境盗忱,而且還支持其他貼心小功能酱床,有了它媽媽再也不用擔(dān)心頻繁環(huán)境切換了。https://github.com/CodeXiaoMai/EnvironmentSwitcher

數(shù)據(jù)類型分類

Java 中的數(shù)據(jù)類型分為兩大類:基本類型對象類型趟佃,相對應(yīng)的變量也分為兩類:基本類型引用類型扇谣。

// int 基本類型的數(shù)據(jù)類型昧捷,num 基本類型的變量,變量的值 10 直接保存在變量 num 中罐寨。
int num = 10;
// String 對象類型的數(shù)據(jù)類型靡挥,str 引用類型的變量,str 中保存的是 "hello" 在內(nèi)存中的首地址鸯绿。
String str = "hello";

下面這張圖代表了變量中保存的值跋破,以及實際對象在內(nèi)存中的情況。


image

當(dāng)修改變量的值時:

num = 20;
str = "java";
image

通過上圖可以看出:

  • 對于基本類型的變量 num瓶蝴,賦值運算符會直接改變它的值毒返,原來的值被覆蓋。
  • 對于引用類型的變量 str舷手,賦值運算符會將 str 中保存的內(nèi)存地址(“hello”的地址)改為新的地址(“java”的地址)拧簸,原來的地址被覆蓋了,但是原來的地址指向的對象(“hello”)不會改變男窟,只是沒有任何引用指向它盆赤,會在垃圾回收機制觸發(fā)時被回收

參數(shù)傳遞

這里首先要記住一點:參數(shù)傳遞就是賦值操作歉眷,也就是說牺六,我們調(diào)用一個帶參的函數(shù)時,形參和實參是兩個變量姥芥,在內(nèi)存中也是開辟了兩個空間兔乞,只是把實參的值賦值給了形參。這是理解 Java 中只有值傳遞的關(guān)鍵凉唐。

下面就通過幾個例子證明這一點庸追。

例1.基本類型的變量傳參

基本類型的變量傳參

輸出結(jié)果:

99

這個很好理解,其實通過編譯器也可以發(fā)現(xiàn)台囱,foo() 方法中的 num 顏色為灰色并且?guī)в胁ɡ司€淡溯,把鼠標(biāo)放到變量上還會看到提示:“Parameter can be converted to a local variable”。意思就是這個變量可以轉(zhuǎn)化為一個本地變量簿训,也就是在方法內(nèi)部聲明咱娶。根據(jù)“參數(shù)傳遞就是賦值操作”,來梳理一下整個過程。當(dāng)調(diào)用 foo() 方法時,將實參( num) 的值賦值給了形參(num1 )杯巨,這時內(nèi)存中存在兩個變量 num(實參)折剃、num1(形參)炕舵,因為基本類型的變量賦值是直接覆蓋操作,所以我們對形參(num1)的操作只是改不了形參的值,而不會影響實參(num) 泣棋。

例2.普通引用類型的變量傳參

說是普通引用類型雕薪,是指類內(nèi)部提供了改變自身的方法昧诱。

普通引用類型的變量傳參

這次可以發(fā)現(xiàn)編譯器沒有提示異常信息,這至少可以證明所袁,在 foo() 方法中對形參 myObject1 進行操作之后盏档,形參 myObject1 仍然被引用,那是不是可以證明形參 myObject1 和實參 myObject 是同一個對象呢燥爷?我們先看看結(jié)果:

100

結(jié)果證明蜈亩,foo 方法中的實參 myObject 和形參 myObject1 確實是指向同一個對象。再根據(jù)“參數(shù)傳遞就是賦值操作”這句話局劲,來梳理一下勺拣。當(dāng)調(diào)用 foo() 方法時,將實參(myObject) 的值(引用對象的內(nèi)存地址)賦值給形參 (myObject1)鱼填,這時內(nèi)存中存在兩個變量 myObject(實參)、myObject1(形參)毅戈,但是它們都指向同一個內(nèi)存地址苹丸,所以我們對形參(myObject1)的操作會影響實參(myObject) 。

例3.特殊引用類型的變量傳參

上面提到了普通引用類型苇经,當(dāng)然就存在特殊引用類型了赘理,它是指自身保存的值不可修改。如:String 和 Integer扇单、Double商模、Boolean 等基本類型的包裝類,它們都是 Immutable 類型的(它們的值都是 final 修飾的)蜘澜,所以每次對它們進行賦值操作施流,都是創(chuàng)建一個新的對象。

特殊引用類型的變量傳參

我們發(fā)現(xiàn) foo() 方法中的 value 被編譯器提示可修改為本地變量鄙信。這就和例 1 中一樣在 foo 方法中對形參的修改不會影響到實參瞪醋,輸出結(jié)果:

hello

這次根據(jù)“參數(shù)傳遞就是賦值操作”以及特殊引用類型的特點來梳理一下。當(dāng)調(diào)用 foo() 方法時装诡,將實參(value) 的值(引用對象的內(nèi)存地址)賦值給形參 (value1)银受,這時內(nèi)存中存在兩個變量 value(實參)、value1(形參)鸦采,而且它們都指向同一個內(nèi)存地址宾巍,但是當(dāng)我們對形參(value1)進行賦值操作時,因為它是一個自身不可修改的特殊引用類型渔伯,所以"hello"對象并沒有修改顶霞,而是在內(nèi)存中又創(chuàng)建了一個值為"java”的新對象,并把“java”的地址賦值給形參咱旱,所以只是形參變了确丢,而實參還是指向“hello”對象绷耍。

例4. 對普通引用類型使用賦值運算符

這次把 foo() 方法進行了修改,在方法內(nèi)對形參進行重新賦值操作鲜侥。

對普通引用類型使用賦值運算符

這時編譯器又提示了形參 myObject 可以修改為本地變量褂始。再根據(jù)“參數(shù)傳遞就是賦值操作”這句話,來梳理一下描函。當(dāng)調(diào)用 foo() 方法時崎苗,將實參(myObject) 的值(引用對象的內(nèi)存地址)賦值給形參 (myObject1),這時內(nèi)存中存在兩個變量 myObject(實參)舀寓、myObject1(形參)胆数,而且它們都指向同一個內(nèi)存地址,但是在方法內(nèi)部又對形參進行了一次賦值操作互墓,這時形參指向了一個新的對象必尼,而實參仍然指向原來的對象,這樣形參和實參之間沒有任何關(guān)聯(lián)了篡撵。所以我們對形參(myObject1)的操作不會影響實參(myObject) 判莉。

其實 foo() 方法等同于:

private static void foo() {
    MyObject myObject = new MyObject();
    myObject.num = 100;
}

同樣可以看出 foo() 方法中的形參和實參完全沒有關(guān)系了。

總結(jié)

Java 中參數(shù)傳遞其實就是賦值操作育谬。
Java 中只存在值傳遞券盅。

  • 對于基本類型變量,是把實參的值直接復(fù)制給形參膛檀。
  • 對于引用類型變量锰镀,是把實參引用的對象的內(nèi)存地址復(fù)制給形參,所以實參和形參指向同一個對象咖刃。
  • 特殊引用類型變量泳炉,因為自身不可變的特點,當(dāng)再次對形參進行賦值操作后僵缺,形參指向一個新的對象胡桃,而實參扔指向原來的對象。特殊引用類型變量包括 String 和一些基本類型的包裝類(Integer磕潮、Double翠胰、Boolean等)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末自脯,一起剝皮案震驚了整個濱河市之景,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膏潮,老刑警劉巖锻狗,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡轻纪,警方通過查閱死者的電腦和手機油额,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刻帚,“玉大人潦嘶,你說我怎么就攤上這事〕缰冢” “怎么了掂僵?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長顷歌。 經(jīng)常有香客問我锰蓬,道長,這世上最難降的妖魔是什么眯漩? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任芹扭,我火速辦了婚禮,結(jié)果婚禮上赦抖,老公的妹妹穿的比我還像新娘冯勉。我一直安慰自己,他們只是感情好摹芙,可當(dāng)我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宛瞄,像睡著了一般浮禾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上份汗,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天盈电,我揣著相機與錄音,去河邊找鬼杯活。 笑死匆帚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的旁钧。 我是一名探鬼主播吸重,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼歪今!你這毒婦竟也來了嚎幸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤寄猩,失蹤者是張志新(化名)和其女友劉穎嫉晶,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡替废,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年箍铭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椎镣。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡诈火,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衣陶,到底是詐尸還是另有隱情柄瑰,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布剪况,位于F島的核電站教沾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏译断。R本人自食惡果不足惜授翻,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望孙咪。 院中可真熱鬧堪唐,春花似錦、人聲如沸翎蹈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荤堪。三九已至合陵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澄阳,已是汗流浹背拥知。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碎赢,地道東北人低剔。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像肮塞,于是被迫代替她去往敵國和親襟齿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,982評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 引言 學(xué)習(xí)過C語言的同學(xué)都很清楚在c中調(diào)用方法的參數(shù)有值傳遞和引用傳遞兩種方式峦嗤。關(guān)于值傳遞和引用傳遞網(wǎng)上有許多的博...
    寧愿呢閱讀 1,395評論 0 4
  • 方法調(diào)用是編程語言中非常重要的一個特性蕊唐,在方法調(diào)用時,通常需要傳遞一些參數(shù)來完成特定功能烁设。 我們首先觀察一個簡單的...
    小人物灌籃閱讀 570評論 0 0
  • 本文首發(fā)于我的個人博客 —— Bridge for You替梨,轉(zhuǎn)載請標(biāo)明出處钓试。 前言 在開始看我畫小狗之前,咱們先來...
    柳樹之閱讀 1,143評論 5 19
  • 今天復(fù)習(xí)Java基礎(chǔ)副瀑,發(fā)現(xiàn)有一個概念好像有點模糊了弓熏,就是值傳遞,Think in Java中說Java只有值傳遞糠睡。...
    莫那一魯?shù)?/span>閱讀 645評論 0 4
  • 昨天有點戲劇化挽鞠,忘了寫了…是的,下班后同事沒帶鑰匙狈孔!進不去家信认,也進不了公司…沒辦法只能在外面訂了了酒店…這個厲害了
    滴滴動力閱讀 239評論 0 0